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

Node.js集群环境下Socket.io无法正常工作求助

Node.js集群环境下Socket.io连接失败(400错误)的解决方案

针对你在Coolify(Traefik反向代理)下部署Node.js集群时遇到的Socket.io连接问题,结合你提供的代码,以下是具体的排查和修复步骤:

1. 修复express-session配置问题

你的session配置存在两处关键错误,这会导致粘性会话失效和Cookie跨域问题:

  • proxy设置错误:部署在Traefik反向代理后,需将proxy设为true,否则session无法正确识别客户端真实IP和代理后的请求。
  • SameSite格式错误:sameSite: 'none; Secure'写法不正确,应分开设置sameSite: 'none'和cookie.secure: true(SameSite=None必须配合Secure属性)。

修正后的session配置:

const sessionConfig = {
    store: new (connectPgStore(expressSession))({}),
    secret: process.env.COOKIE_SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: {
        maxAge: 30 * 24 * 60 * 60 * 1000,
        proxy: true, // 修改为true
        secure: true, // 添加Secure属性
        httpOnly: true // 建议添加,提升安全性
    },
    sameSite: 'none' // 单独设置SameSite
}

2. 将Session中间件附加到Socket.io握手流程

Socket.io的连接请求不会自动经过express的session中间件,需手动将session中间件绑定到Socket.io的握手阶段,确保集群实例能识别同一个客户端的session:

// 在创建io实例后添加
io.use((socket, next) => {
  sessesionMiddleware(socket.request, socket.request.res || {}, next);
});

3. 配置Socket.io的CORS和传输选项

在反向代理环境下,需明确配置Socket.io的CORS规则,避免跨域错误;同时指定传输方式,优先使用WebSocket:

const io = new Server(server, {
    adapter: createAdapter(pubClient, subClient),
    cors: {
        origin: process.env.FRONTEND_URL, // 替换为你的前端域名
        credentials: true, // 允许携带Cookie
        allowedHeaders: ['Content-Type', 'Authorization']
    },
    transports: ['websocket', 'polling'], // 优先WebSocket,降级到轮询
    pingTimeout: 60000 // 延长超时时间,避免代理环境下的连接中断
});

4. 确保Traefik(Coolify)开启粘性会话和WebSocket支持

Coolify基于Traefik,需完成以下配置:

  • 开启粘性会话:在Coolify应用的「反向代理」设置中,启用「Sticky Sessions」,指定Cookie名称(可使用你的session Cookie名,比如connect.sid)。
  • 启用WebSocket转发:在Coolify应用设置中开启「WebSocket Support」,确保Traefik正确转发Upgrade和Connection请求头。

5. 验证Redis适配器的初始化

确保Redis客户端正确创建并连接,避免因Redis连接失败导致集群通信异常:

// 补充pubClient的创建代码
const pubClient = new Redis({
    host: process.env.REDIS_HOST,
    port: process.env.REDIS_PORT,
    password: process.env.REDIS_PASSWORD,
    db: process.env.REDIS_DB || 0
});

const subClient = pubClient.duplicate();

// 监听Redis连接错误
pubClient.on('error', (err) => console.error('Redis pub client error:', err));
subClient.on('error', (err) => console.error('Redis sub client error:', err));

6. 排查日志定位问题

  • 查看Node.js集群实例的日志,确认是否收到Socket.io的握手请求,以及是否有session验证错误。
  • 查看Traefik的日志,检查请求是否正确转发到后端实例,是否有400错误的具体原因。
  • 检查前端控制台的Network请求,查看Socket.io握手请求的响应头和Cookie是否正确携带。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:06:00