AWS Elastic Beanstalk部署Django应用HTTPS下WebSocket连接失败
搞定AWS Elastic Beanstalk上Django WebSocket的HTTPS连接问题
你说的这个WebSocket is closed before the connection is established错误,只在HTTPS环境出现、HTTP完全正常的情况,我帮你梳理下最可能的问题点和修复步骤:
1. 先捋清ALB的HTTPS监听配置
从你贴的负载均衡器截图来看,得确认443端口的HTTPS监听是不是正确转发WebSocket请求:
- 目标组必须指向EC2实例的5000端口(也就是你的Daphne服务端口),而且目标组的健康检查要配置对——比如用5000端口的某个健康端点(比如Django的
/health接口)。 - ALB本身原生支持WebSocket,但要保证监听规则没拦截
Upgrade头,目标组的协议选HTTP就行(因为WebSocket是基于HTTP升级机制实现的)。
2. 修复Apache的SSL重写配置
你当前的SSL配置里缺了关键的WebSocket转发规则,导致HTTPS下的Upgrade请求没正确传递给Daphne。把/etc/httpd/conf.d/ssl_rewrite.conf改成下面这样:
RewriteEngine On ProxyRequests Off # 专门处理WebSocket的升级请求,转发到本地Daphne的5000端口 RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC] RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC] RewriteRule /(.*) ws://localhost:5000/$1 [P,L] # 把HTTP请求重定向到HTTPS <If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'"> RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L] </If>
核心就是新增的那行RewriteRule,它会把WebSocket的升级请求直接转发到本地的Daphne服务,避免Apache拦截HTTPS下的WebSocket请求。
3. 修改JavaScript的连接地址
你现在用的是<IPv4 Public IP>:5000,这在HTTPS环境里有两个问题:
- SSL证书一般绑定域名,直接用IP的话,浏览器会因为证书不匹配拒绝建立连接;
- 不需要手动指定5000端口,ALB的443端口会自动把请求转发到实例的5000端口。
改成用Elastic Beanstalk分配的域名就行,比如:
const ws_path = 'wss://your-app.elasticbeanstalk.com'; const websocket = new ReconnectingWebSocket(ws_path, null, {maxReconnectAttempts: 5, timeoutInterval: 5000});
4. 验证Daphne和目标组状态
- 登录到EC2实例,执行
supervisorctl status daphne查看Daphne服务是否正常运行,再检查/var/log/stdout_daphne.log日志有没有报错; - 去AWS控制台查看ALB的目标组,确认5000端口的实例状态是健康的。如果不健康,检查安全组规则——必须允许ALB的安全组访问实例的5000端口。
5. 最后检查安全组配置
- EC2实例的安全组:入站规则要开放5000端口给ALB的安全组,同时开放80/443端口(因为Apache在处理HTTP/HTTPS请求);
- ALB的安全组:入站规则要允许所有IP访问80/443端口。
按这些步骤调整后,HTTPS环境下的WebSocket连接应该就能正常建立了。
内容的提问来源于stack exchange,提问作者mohamed.alsum
相关产品推荐
相关产品推荐

