You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Socket.io客户端卡在101状态,持续XHR轮询求助

Socket.io Websocket 协议升级失败问题解决

问题背景

我通过Nginx反向代理搭建了基于Express和Socket.io的SSL服务,目前消息收发看似正常,但仅支持轮询方式;当强制设置transports: ['websocket']时,请求返回101协议切换状态,但实际未完成Websocket协议升级。

服务端代码

const { v4: uuidV4 } = require('uuid')
const express = require('express')
const app = express()
const fs = require('fs')
const https = require('https')
const options = {
  key: fs.readFileSync('/etc/ssl/xxx/ssl.key'),
  cert: fs.readFileSync('/etc/ssl/xxx/ssl.combined'),
}
const httpsServer = https.createServer(options, app)
httpsServer.listen(3000, function () {
  console.log("Example app listening at %s",  httpsServer.address().port);
});

const io = require("socket.io")(httpsServer);

Nginx配置

location / {
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass https://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    listen 161.97.166.96:443 ssl;
    ssl_certificate /etc/ssl/xxx/ssl.combined;
    ssl_certificate_key /etc/ssl/xxx/ssl.key;

解决步骤

  1. 修复Nginx Connection头配置
    硬编码"upgrade"会导致非Websocket请求出现冲突,替换成动态匹配的配置:

    • 先在Nginx的http块中添加映射规则:
      map $http_upgrade $connection_upgrade {
          default upgrade;
          '' close;
      }
      
    • 然后将location块中的proxy_set_header Connection "upgrade";改为:
      proxy_set_header Connection $connection_upgrade;
      
  2. 调整Socket.io服务端配置
    由于是反向代理环境,需要让Socket.io信任代理并正确识别客户端请求,修改初始化代码:

    const io = require("socket.io")(httpsServer, {
      cors: {
        origin: "https://你的实际域名", // 替换成你的业务域名
        methods: ["GET", "POST"]
      },
      transports: ["websocket", "polling"], // 优先尝试Websocket,失败自动降级轮询
      trustProxy: true // 启用反向代理信任
    });
    
  3. 规范客户端连接配置
    不要仅强制['websocket'],保留降级逻辑,确保连接稳定性:

    const socket = io("https://你的实际域名", {
      transports: ["websocket", "polling"],
      reconnection: true
    });
    
  4. 检查SSL证书一致性
    确保Nginx和Node.js服务使用完全一致的SSL证书文件,若存在CA根证书,补充到Node.js的https配置中:

    const options = {
      key: fs.readFileSync('/etc/ssl/xxx/ssl.key'),
      cert: fs.readFileSync('/etc/ssl/xxx/ssl.combined'),
      ca: fs.readFileSync('/etc/ssl/xxx/ssl.ca') // 如有CA证书则添加
    }
    
  5. 日志排查验证

    • 查看Nginx错误日志:tail -f /var/log/nginx/error.log
    • 在服务端添加连接日志,确认传输方式:
      io.on('connection', (socket) => {
        console.log('客户端连接成功,传输方式:', socket.conn.transport.name);
        socket.on('disconnect', () => {
          console.log('客户端断开连接');
        });
      });
      

内容的提问来源于stack exchange,提问作者AntonioCorrenti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 15:15:46