如何检测指定socket.id是否已加入特定Socket.io房间?
Socket.io检测客户端socket.id是否在指定房间的实现方法
问题场景
我正在开发一个Socket.io应用,需要检测客户端的socket.id是否处于特定房间中,该如何实现?
我的代码如下:
import { socketIds } from "../models/connection/connectionEvents.js"; //socketIds是存储所有已连接客户端的全局对象 export async function informOperator(io,senderSocketId,conversationData,eventName,eventData) { try { //在全局数组socketIds中查找操作员的socket id Object.entries(socketIds).forEach(([socketId, user]) => { if ( senderSocketId !== socketId && user.userId.find(userId => conversationData.operators.includes(userId)) ) { //我想在此处检测socketId是否在房间conversationData._id中 io.to(socketId).emit(eventName,...eventData) } }); } catch (error) { throw error; } }
使用版本:
- "socket.io": "^4.5.4"
- "socket.io-client": "^4.5.4"
已尝试的无效方法:
io.sockets.manager.rooms['/' + room].indexOf(socket.id) >= 0const socketInRoom = room.has(socketId);
解决方案
在Socket.io 4.x版本中,需通过官方提供的当前版本API实现检测,具体如下:
修改后的完整代码
import { socketIds } from "../models/connection/connectionEvents.js"; //socketIds是存储所有已连接客户端的全局对象 export async function informOperator(io,senderSocketId,conversationData,eventName,eventData) { try { const targetRoomId = conversationData._id; //在全局数组socketIds中查找操作员的socket id Object.entries(socketIds).forEach(([socketId, user]) => { if ( senderSocketId !== socketId && user.userId.some(userId => conversationData.operators.includes(userId)) ) { // 获取目标客户端的socket实例 const targetSocket = io.sockets.sockets.get(socketId); // 检测socket实例存在且处于目标房间 if (targetSocket && targetSocket.rooms.has(targetRoomId)) { io.to(socketId).emit(eventName,...eventData); } } }); } catch (error) { throw error; } }
关键说明
io.sockets.sockets是Socket.io 4.x中存储所有已连接socket实例的Map对象,通过get(socketId)可精准获取对应客户端的socket实例。- 每个socket实例的
rooms属性是Set集合,存储了该客户端加入的所有房间ID,使用has(roomId)可高效判断是否在目标房间内。 - 之前尝试的方法基于旧版本Socket.io API,4.x已废弃
io.sockets.manager这类属性,因此无法生效。
内容的提问来源于stack exchange,提问作者Hamoudeh Fouad
相关产品推荐
相关产品推荐

