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

Node.js集群环境下如何获取Socket.io全量房间列表?

解决Node.js集群环境下Socket.io全实例房间列表获取问题

你的问题核心在于:集群模式下每个Worker进程仅维护自身实例内的Socket连接与房间数据,@socket.io/cluster-adapter负责的是跨Worker的事件同步(如广播、房间操作),但并未提供全局房间列表的直接查询能力。要获取所有32个实例的全部房间,需要通过主进程-子进程IPC通信实现跨Worker的数据汇总。

实现方案

1. 主进程作为数据汇总中心

主进程负责向所有Worker发送房间查询指令,并收集各Worker返回的房间列表,最终去重后得到全局活跃房间。

2. Worker进程响应查询并上报数据

每个Worker维护自身的房间查询逻辑,收到主进程指令后返回本地活跃房间,同时可通过监听房间生命周期事件,主动向主进程上报房间的创建/销毁,提升数据实时性。

完整代码示例

主进程代码

const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isPrimary) {
  // 用Set存储全局房间,自动去重
  const globalActiveRooms = new Set();

  // 监听Worker发送的消息
  cluster.on('message', (worker, message) => {
    switch (message.type) {
      case 'report-rooms':
        // 批量添加Worker上报的房间
        message.rooms.forEach(room => globalActiveRooms.add(room));
        break;
      case 'room-created':
        globalActiveRooms.add(message.room);
        break;
      case 'room-destroyed':
        globalActiveRooms.delete(message.room);
        break;
    }
  });

  // 对外提供获取全局房间的方法(可结合HTTP接口暴露)
  function getGlobalActiveRooms() {
    // 主动触发所有Worker上报当前房间
    Object.values(cluster.workers).forEach(worker => {
      worker.send({ type: 'get-local-rooms' });
    });
    return Array.from(globalActiveRooms);
  }

  // 启动所有Worker进程
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  // Worker进程代码
  const http = require('http');
  const { Server } = require('socket.io');
  const { createAdapter } = require('@socket.io/cluster-adapter');

  const server = http.createServer();
  const io = new Server(server);

  // 启用cluster-adapter实现跨Worker事件同步
  io.adapter(createAdapter());

  // 你的原有本地房间查询逻辑
  function getLocalActiveRooms() {
    const roomsArr = Array.from(io.sockets.adapter.rooms);
    // 过滤掉以socketId命名的个人房间
    return roomsArr.filter(room => !room[1].has(room[0])).map(item => item[0]);
  }

  // 监听主进程的查询指令
  process.on('message', (message) => {
    if (message.type === 'get-local-rooms') {
      const localRooms = getLocalActiveRooms();
      process.send({ type: 'report-rooms', rooms: localRooms });
    }
  });

  // 监听房间创建/销毁事件,主动上报主进程
  io.on('connection', (socket) => {
    // 用户加入房间时上报
    socket.on('join-room', (room) => {
      socket.join(room);
      process.send({ type: 'room-created', room });
    });

    // 用户断开时检查房间是否为空,为空则上报销毁
    socket.on('disconnecting', () => {
      Array.from(socket.rooms).forEach(room => {
        const roomClientCount = io.sockets.adapter.rooms.get(room)?.size || 0;
        // 当前socket是房间最后一个连接,房间即将销毁
        if (roomClientCount === 1) {
          process.send({ type: 'room-destroyed', room });
        }
      });
    });
  });

  server.listen(3000);
}

关键说明

  1. IPC通信机制:利用Node.js集群模块的process.send()和cluster.on('message')实现主从进程的数据交互,这是跨Worker共享数据的原生方案。
  2. 数据去重:用Set存储全局房间,避免同一房间被多个Worker重复上报。
  3. 实时性优化:通过监听房间的创建/销毁事件主动上报,减少主动查询的频率,同时可定时触发全量查询(如每分钟一次)来修正数据误差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:12:25