Socket.io向房间广播消息时发送者也收到,与文档不符寻求解决
问题原因
你获取房间的方式有误:Socket.io 中每个 Socket 会自动加入以自身 ID 命名的专属房间,socket.rooms 是一个包含所有已加入房间的 Set,解构取第一个元素(const [thisRoom] = socket.rooms)大概率拿到的是当前 Socket 的 ID,而非你期望的自定义房间。
当你调用 socket.to(thisRoom).emit(...) 时,若 thisRoom 是 Socket 自身的 ID,这个房间里只有当前 Socket 自己。虽然 socket.to() 本意是排除当前 Socket,但由于房间内没有其他客户端,Socket.io 内部逻辑可能导致消息仍回发给了自己;或者你实际加入的自定义房间与 Socket ID 同名(这种情况极少),导致 socket.to() 无法正确排除。
解决方法
正确过滤获取自定义房间
若你只让 Socket 加入了一个自定义房间,可以通过过滤掉 Socket ID 的方式获取目标房间:socket.on('slots', (slots) => { console.log(socket.id); // 过滤掉Socket自身ID,提取自定义房间 const thisRoom = Array.from(socket.rooms).find(room => room !== socket.id); console.log(thisRoom); if (thisRoom) { socket.to(thisRoom).emit('slots', slots); } });用自定义属性存储房间名(更可靠)
在调用socket.join(roomName)加入房间时,直接将房间名存到 Socket 的自定义属性中,后续直接取用:// 加入房间时的代码 const targetRoom = 'your-room-name'; socket.join(targetRoom); socket.currentRoom = targetRoom; // 处理消息转发的代码 socket.on('slots', (slots) => { console.log(socket.id); console.log(socket.currentRoom); socket.to(socket.currentRoom).emit('slots', slots); });验证所有已加入房间
打印完整的房间列表,确认目标房间是否存在:console.log('当前Socket已加入的所有房间:', Array.from(socket.rooms));
确认房间正确后,socket.to(room).emit() 就只会将消息发送给房间内除当前 Socket 外的其他客户端,不会再出现原始客户端收到转发消息的情况。
内容的提问来源于stack exchange,提问作者El Xando
相关产品推荐
相关产品推荐

