Apache2.4+HTTPS环境下WebSocket无法连接的配置问题排查
Apache2.4 转发WebSocket至Python Socket.IO服务器的配置问题
问题场景
当前环境:Apache2.4 搭配 Django 框架,使用 Python socketio 库实现 Socket 连接。后端 Socket.IO 服务器监听 8091 端口,Apache 的 HTTPS 端口为 8080,HTTP 端口为 8088。客户端连接时抛出 socketio.exceptions.ConnectionError: Connection error。
现有 Apache 配置:
httpd.conf
Listen 8088 LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so LoadModule rewrite_module modules/mod_rewrite.so Include conf/extra/httpd-ssl.conf
httpd-ssl.conf
Listen 8080 <VirtualHost _default_:8080> SSLProxyEngine On RewriteEngine On RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /(.*) ws://localhost:8091/$1 [P,L] </VirtualHost>
客户端连接代码:
import socketio sio = socketio.Client() sio.connect("https://<server_ip>:8080/", transports=["websocket"])
配置修改方案
需要调整 Apache 配置,当前配置存在三处关键缺失,修改如下:
- 补充ProxyPass规则
Socket.IO 除了 WebSocket 握手请求,还有初始 HTTP 握手请求,仅靠 RewriteRule 无法完整转发。需在 VirtualHost 中添加:
ProxyPass /socket.io/ http://localhost:8091/socket.io/ ProxyPassReverse /socket.io/ http://localhost:8091/socket.io/
若后端自定义了 Socket.IO 路径,替换为对应路径即可。
- 精准匹配WebSocket转发规则
原规则会误转发所有路径的请求,修改为仅匹配 Socket.IO 路径:
RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /socket.io/(.*) ws://localhost:8091/socket.io/$1 [P,L]
- 完善SSL基础配置
当前 VirtualHost 缺少 SSL 证书配置,会导致 HTTPS 连接失败,必须添加证书路径:
SSLEngine on SSLCertificateFile "/path/to/your/cert.crt" SSLCertificateKeyFile "/path/to/your/private.key"
替换为实际的证书和私钥文件路径。
- 加载proxy_http_module模块
Socket.IO 初始握手依赖 HTTP 代理模块,在 httpd.conf 中添加:
LoadModule proxy_http_module modules/mod_proxy_http.so
修改后的完整 httpd-ssl.conf 示例:
Listen 8080 <VirtualHost _default_:8080> SSLEngine on SSLCertificateFile "/path/to/cert.crt" SSLCertificateKeyFile "/path/to/private.key" SSLProxyEngine On RewriteEngine On # 转发WebSocket请求 RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /socket.io/(.*) ws://localhost:8091/socket.io/$1 [P,L] # 转发Socket.IO的HTTP握手请求 ProxyPass /socket.io/ http://localhost:8091/socket.io/ ProxyPassReverse /socket.io/ http://localhost:8091/socket.io/ # 如需转发Django其他请求,添加以下规则(根据实际端口调整) # ProxyPass / http://localhost:8000/ # ProxyPassReverse / http://localhost:8000/ </VirtualHost>
额外检查项
- 确认后端 Socket.IO 服务器在 8091 端口正常运行,可通过 Apache 本地执行
curl http://localhost:8091/socket.io/测试连通性。 - 替换客户端代码中的
<server_ip>为实际服务器 IP,确保 8080 端口对外开放。 - 检查服务器防火墙规则,允许 8080、8091 端口的入站/出站通信。
内容的提问来源于stack exchange,提问作者Ajk
相关产品推荐
相关产品推荐

