更换域名后WebSocket连接失败问题求助
问题描述
我正在开发一个基于WebSocket通信的回合制游戏,本地运行一切正常,之前在同一服务器的旧域名上也能正常工作,但更换新域名后,控制台突然抛出错误:
WebSocket connection to 'wss://example.com/socket.io/?EIO=4&transport=websocket' failed: createSocket @ index-WoxGCKpd.js:26...
我已经把旧域名的openlitespeed.conf配置复制到新域名上,服务器代码也没有改动。当前80端口的虚拟主机配置如下(443端口配置完全相同):
virtualHost example.com-80 { ProxyPass / http://127.0.0.1:5000/ ProxyPassReverse / http://127.0.0.1:5000/ ProxyPass /socket.io/ ws://127.0.0.1:5000/socket.io/ ProxyPassReverse /socket.io/ ws://127.0.0.1:5000/socket.io/ user admin ... #VirtualHost config settings ... rewrite { enable 1 autoLoadHtaccess 1 RewriteCond %{HTTP:X-Forwarded-Proto} https [NC] RewriteRule . - [E=HTTPS:on] RewriteCond %{HTTPS} !=on RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC] RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # Mail auto configuration (Thunderbird) RewriteRule ^/\.well-known/autoconfig/mail/config-v1\.1\.xml$ http://dainternal/$0 [P,L] } # include aliases include /usr/local/lsws/conf/httpd-alias.conf extprocessor nodejs{ type proxy address 127.0.0.1:5000 maxConns 2000 initTimeout 20 retryTimeout 0 respBuffer 0 } context / { type proxy handler nodejs addDefaultCharset off } context /socket.io { type proxy handler nodejs location 127.0.0.1:5000 allowBrowse 1 addResponseHeader Connection "Upgrade, Keep-Alive" addResponseHeader Upgrade "websocket" proxySetHeader Upgrade $http_upgrade; proxySetHeader Connection "Upgrade"; proxySetHeader Host $host; proxySetHeader X-Real-IP $remote_addr; proxySetHeader X-Forwarded-For $proxy_add_x_forwarded_for; proxySetHeader X-Forwarded-Proto $scheme; websocket 1 } }
我已经尝试了以下排查步骤,但问题仍未解决:
- 域名SSL已配置正常,HTTPS访问无问题
- 本地环境依然可以正常运行游戏和WebSocket通信
- 更新了CORS设置,允许
localhost和example.com作为请求源 - 主机服务商确认没有防火墙或端口开放的相关限制
现在完全不知道该从哪里入手,求各位大佬给点排查思路!
排查方向与解决方案建议
1. 清理重复的代理配置,避免冲突
你的配置里同时存在ProxyPass /socket.io/规则和context /socket.io的专门代理配置,这很可能导致请求处理逻辑冲突。OpenLiteSpeed中context的优先级更高,重复的ProxyPass规则反而会干扰WebSocket请求的转发。建议直接删除这两行:
ProxyPass /socket.io/ ws://127.0.0.1:5000/socket.io/ ProxyPassReverse /socket.io/ ws://127.0.0.1:5000/socket.io/
修改后记得重启OpenLiteSpeed服务生效。
2. 验证HTTPS环境下的请求头传递
因为你的站点强制HTTPS,需要确保WebSocket请求的X-Forwarded-Proto头被正确设置为https。可以在Node.js服务中打印请求头,确认req.headers['x-forwarded-proto']的值是否为https。如果不是,检查443端口虚拟主机的context /socket.io配置中,proxySetHeader X-Forwarded-Proto $scheme是否正确生效($scheme在HTTPS环境下应该是https)。
3. 确认Socket.IO服务端的代理信任配置
Socket.IO服务端需要明确信任反向代理的请求头,否则可能无法正确完成握手。在Node.js代码中添加trustProxy: true配置:
const io = require('socket.io')(server, { cors: { origin: ["https://example.com", "http://localhost:你的本地端口"], methods: ["GET", "POST"] }, trustProxy: true // 关键配置,信任反向代理的请求头 });
同时再次确认CORS的origin列表已经包含新域名,没有拼写错误。
4. 查看OpenLiteSpeed的日志定位问题
OpenLiteSpeed的日志目录通常是/usr/local/lsws/logs/,重点查看error.log和access.log:
- 检查WebSocket请求的状态码,比如是否出现404、502等错误
- 查看日志中是否有代理转发失败的报错信息,这能快速定位是代理配置问题还是后端服务未正确响应
5. 直接测试后端WebSocket服务
在服务器上安装wscat工具(npm install -g wscat),然后执行:
wscat -c ws://127.0.0.1:5000/socket.io/?EIO=4&transport=websocket
如果能正常连接并收到Socket.IO的响应,说明后端服务没问题,问题出在OpenLiteSpeed的代理配置;如果连接失败,那可能是后端服务的Socket.IO配置有误,或者服务未正常启动。
6. 检查浏览器网络请求细节
打开浏览器开发者工具的Network标签,找到WebSocket请求,查看:
- 请求头中的
Upgrade是否为websocket,Connection是否为Upgrade - 是否出现3xx重定向:如果WebSocket请求被强制HTTPS重定向,可能会导致握手失败,此时需要调整Rewrite规则,确保WebSocket请求不会被错误重定向
备注:内容来源于stack exchange,提问作者eligolf

