在使用 Nginx 代理 Socket.IO 服务时,经常会遇到一些连接问题。以下是常见问题及其解决方案:
问题表现:Socket.IO 降级到轮询(polling)而非使用 WebSocket
解决方案:
location /socket.io/ {
proxy_pass http://socket.io_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
# 以下两行对于 WebSocket 很重要
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
问题表现:连接频繁断开或超时
解决方案:
location /socket.io/ {
# ... 其他配置同上 ...
# 增加超时设置
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 86400s;
}
问题表现:在多服务器环境下,Socket.IO 会话不一致
解决方案:
upstream socketio_nodes {
ip_hash; # 确保同一客户端始终连接到同一后端服务器
server 127.0.0.1:3000;
server 127.0.0.1:3001;
# ... 其他服务器
}
问题表现:跨域请求被拒绝
解决方案:
location /socket.io/ {
# ... 其他配置 ...
# CORS 设置
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
问题表现:Socket.IO 无法正确处理路径
解决方案:
location /socket.io/ {
# 确保路径正确传递
proxy_set_header X-Forwarded-Path /socket.io/;
proxy_redirect off;
}
问题表现:大数据量传输时出现问题
解决方案:
location /socket.io/ {
# ... 其他配置 ...
# 调整缓冲区大小
proxy_buffers 8 32k;
proxy_buffer_size 64k;
}
upstream socketio_nodes {
ip_hash;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
listen 80;
server_name example.com;
location /socket.io/ {
proxy_pass http://socketio_nodes;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 86400s;
# CORS 设置
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
}
}
确保客户端也正确配置:
const socket = io('https://example.com', {
path: '/socket.io', // 与 Nginx 配置一致
transports: ['websocket', 'polling'], // 显式指定传输方式
secure: true // 如果使用 HTTPS
});
通过以上配置,应该能够解决大多数 Nginx 代理 Socket.IO 的常见问题。如果仍有问题,建议检查 Nginx 错误日志和 Socket.IO 服务器的日志以获取更多调试信息。