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); }
关键说明
- IPC通信机制:利用Node.js集群模块的
process.send()和cluster.on('message')实现主从进程的数据交互,这是跨Worker共享数据的原生方案。 - 数据去重:用
Set存储全局房间,避免同一房间被多个Worker重复上报。 - 实时性优化:通过监听房间的创建/销毁事件主动上报,减少主动查询的频率,同时可定时触发全量查询(如每分钟一次)来修正数据误差。
内容的提问来源于stack exchange,提问作者born2net
相关产品推荐
相关产品推荐

