本地正常但EC2上NodeJS Socket连接失败排查求助
我们已将ReactJS前端、NodeJS后端及采用Socket编程实现通信的NodeJS聊天服务部署在AWS EC2(t2.medium实例)上,使用Nginx作为Web服务器。
以下是我在/etc/nginx/nginx.conf中添加的配置(为保密已修改服务器名称):
server { listen 80; listen [::]:80; server_name <value>.in www.<value>.in; # Redirect all HTTP requests to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name <value>.in www.<value>.in; root /var/www/html/dist; index index.html; ssl_certificate /etc/letsencrypt/live/<value>.in/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/<value>.in/privkey.pem; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { try_files $uri $uri/ /index.html; } location /api { proxy_pass http://localhost:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /socket { proxy_pass http://localhost:3001; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
该服务在本地运行正常,但部署到EC2后,前端客户端无法与Socket服务器建立连接。我已完成以下排查操作:
- 安全组已允许所有流量;
- 端口已开放,可通过Telnet连通。
此外还检查了端口权限和防火墙设置,多次调整配置均无效,请问我哪里操作有误?还遗漏了什么配置?
针对Socket连接失败的问题,结合你的Nginx配置和已做的排查,以下是几个关键的遗漏点和修正方案:
1. 补充WebSocket必需的HTTP版本配置
WebSocket握手依赖HTTP/1.1协议,你的Nginx配置中缺少proxy_http_version 1.1,这会导致代理握手失败。需要在location /socket块中添加该配置:
location /socket { proxy_pass http://localhost:3001; proxy_http_version 1.1; # 新增此配置 proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
2. 调整路径匹配规则(避免路径拼接错误)
如果你的Socket服务器监听的是根路径(/),需要确保Nginx代理时路径拼接正确。可以将location /socket改为location /socket/,同时proxy_pass末尾加上斜杠:
location /socket/ { proxy_pass http://localhost:3001/; # 其余配置保持不变 }
这样能避免Nginx将/socket作为前缀附加到后端请求路径中,导致Socket服务器无法识别请求。
3. 添加长连接超时配置
默认Nginx超时设置会断开WebSocket长连接,需在location /socket块中添加超时参数:
proxy_read_timeout 86400; # 保持长连接超时时间,可按需调整 proxy_send_timeout 86400; proxy_connect_timeout 7d;
4. 确认前端Socket连接地址正确性
前端必须使用wss://<你的域名>/socket作为连接地址,禁止使用ws://localhost:3001或EC2实例IP。因为HTTPS环境下浏览器会拦截非安全的ws协议请求,必须使用加密的wss协议。
5. 检查Socket服务器绑定地址
确保Socket服务器绑定的是0.0.0.0而非localhost/127.0.0.1——虽然本地代理理论上能访问回环地址,但部分Socket库存在绑定限制,改为0.0.0.0可确保服务监听所有可用接口。
6. 通过日志定位具体错误
- 查看Nginx错误日志:
sudo tail -f /var/log/nginx/error.log,检查是否有代理失败的记录; - 查看Socket服务器日志,确认是否收到前端连接请求,是否有报错信息。
内容的提问来源于stack exchange,提问作者stan3098

