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

PM2集群模式下Socket.io跨实例广播失败该如何解决

问题根因

报错Error: The client is closed是因为你使用的Redis v4.x版本API有变动:

  1. 创建客户端后不会自动建立连接,需要手动调用connect方法
  2. 连接配置的结构与旧版不同,host/port需要放到socket属性下,鉴权字段从auth_pass改为password

另外你的代码还有两个可优化点:

  • 不需要手动给subClient赋值psubscribe方法,Redis v4已原生支持
  • 定时器不要放到connection回调中,否则每有一个新客户端连接到实例0就会新增一个定时器,导致消息重复发送

修正后的服务端index.js代码

const { Server } = require("socket.io")
const { createAdapter } = require("@socket.io/redis-adapter");
const { createClient } = require("redis");

const io = new Server({ transports: ['websocket'] })

// Redis v4 配置写法
const pubClient = createClient({
  socket: {
    host: 'localhost',
    port: 6379
  },
  password: "root"
});
const subClient = pubClient.duplicate();

// 等待Redis连接成功后再挂载适配器
Promise.all([
  pubClient.connect(),
  subClient.connect()
]).then(() => {
  io.adapter(createAdapter(pubClient, subClient))
}).catch(err => {
  console.error('Redis连接失败', err)
})

io.listen(3000)

// 定时器放到全局,仅实例0启动一次
if(process.env.NODE_APP_INSTANCE == 0){
  setInterval(() => {
    io.emit('test_msg', 'server: ' + process.env.NODE_APP_INSTANCE)
  }, 5000)
}

io.on("connection", (socket) => {
  console.log(socket.id + ' connected on server: ' + process.env.NODE_APP_INSTANCE)
});

验证步骤

  1. 确认本地Redis服务已正常启动,密码配置为root
  2. 重启PM2集群:pm2 reload ecosystem.config.js
  3. 启动多个客户端进程测试,所有客户端都会收到实例0推送的test_msg事件,服务端不会再抛出Redis客户端关闭的错误

你的PM2配置无需修改,集群模式下多个Node.js进程可以共享监听同一个端口,PM2会自动完成负载均衡。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:15:07