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

Socket.IO v4加入房间时如何获取房间内已存在的在线Socket用户列表

Socket.IO v4 获取房间在线连接列表的正确实现

为什么你之前的代码会失效

Socket.IO v4 对内部适配器的存储结构做了调整,同时废弃了多个旧版便捷方法:

  • 旧版中io.sockets.adapter.rooms是普通对象结构,可以直接通过方括号按房间ID取值;但v4中这个属性被替换为原生Map实例,用方括号取值的方式本身就无法获取Map中的值
  • 就算通过Map方法拿到了对应的房间实体,v4里的房间实体是直接以socketId为键的Map结构,不存在旧版嵌套的.sockets属性,链式访问sockets属性自然会返回undefined
  • 旧版的io.sockets.clients(roomName)便捷查询接口从v3版本开始就被彻底移除,在v4中完全不存在

v4 官方提供的标准获取房间连接的方法

v4 专门开放了io.in(roomName).fetchSockets()异步方法,可以直接返回对应房间下所有的服务端Socket连接实例数组,这个方法是适配当前版本的正式API,没有版本兼容问题。

结合你现有业务逻辑的改造代码

把你原来的join chat事件逻辑替换成下面的实现:

socket.on('join chat', async ({ chat, userId }) => {
  // 先执行加入房间的操作
  socket.join(chat.id);

  // 异步获取当前房间内所有的Socket连接实例
  const roomSockets = await io.in(chat.id).fetchSockets();
  // 从连接实例中提取所有已加入房间的用户ID列表(需要提前在连接时绑定userId到socket对象)
  const onlineUserIds = roomSockets.map(socket => socket.data.userId);

  // 原有逻辑:给会话内其他常驻用户推送新用户加入的通知
  if (!chat.users) return console.log('users not defined');
  chat.users.forEach(user => {
    if (user._id === userId) return;
    socket.in(user._id).emit('user joined', userId);
  });

  // 新增逻辑:把当前房间的在线用户列表发给刚加入的新用户
  socket.emit('room online users', onlineUserIds);

  console.log(`User with id ${userId} joined chat with id ${chat.id}`);
});

配套注意事项

  • 在客户端建立Socket连接的阶段,需要先把用户ID绑定到socket的data属性上,不然从socket实例上取userId会取不到:
// 服务端连接建立阶段的绑定代码
io.on('connection', (socket) => {
  const userId = socket.handshake.auth.userId;
  socket.data.userId = userId;
});
  • 如果需要同步获取而非等待Promise返回,可以直接调用内部适配器的Map结构取值,但这种写法不推荐用于生产环境:
// 同步获取的写法(直接访问内部结构,版本升级可能存在兼容变动)
const room = io.sockets.adapter.rooms.get(chat.id);
// 提取房间内所有的socketId,再结合本地存储的socketId和userId映射关系得到在线用户列表
const connectedSocketIds = room ? [...room.keys()] : [];

注意:直接访问内部adapter结构的写法没有官方兼容承诺,生产环境优先用官方开放的fetchSockets()方法,避免后续版本升级出现兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 02:15:03