Socket.io获取当前socket所在的房间

28

是否有可能获取当前插座所在的房间,而不必调用

io.sockets.clients(roomName)

对于每个房间名称,查找在结果中是否存在该插座。

12个回答

44
在socket.io 1版本及以上,语法如下:
socket.rooms

4
socket.rooms 在版本 1.3.6 中显示为空白... 对你仍然有效吗?(意思是询问对方是否仍然能够正常使用该功能) - Crashalot
3
返回undefined,版本:1.6.0。 - Mr. B.
2
对我来说,它返回一个空对象 {},我正在使用2.3.0版本。 - Dylan
我也在使用2.3.0版本,但它似乎对我有效?即使没有调用 socket.join() ,它也会返回一个等于 socket id 的频道。也许你没有在连接函数内调用它?或者你的连接函数参数不是 socket - cytsunny

13

跨平台的方式

var rooms = Object.keys(io.sockets.adapter.sids[socket.id]);
// returns [socket.id, 'room-x'] or [socket.id, 'room-1', 'room-2', ..., 'room-x']

13

更新:Socket.io 3.0 发布


3.x 版本中,Socket.rooms 现在是一个 Set,这意味着房间中的值可能只会出现一次

结构示例:Set(4) {"<socket ID>", "room1", "room2", "room3"}

io.on("connect", (socket) => {
  console.log(socket.rooms); // Set { <socket.id> }
  socket.join("room1");
  console.log(socket.rooms); // Set { <socket.id>, "room1" }
});

检查特定房间:

socket.rooms.has("room1"); // true

了解 Set 和可用方法的更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

迁移文档:https://socket.io/docs/migrating-from-2-x-to-3-0/


12
Socket.IO Room文档中得知:

io.sockets.manager.roomClients[socket.id]

的意思是"客户端加入的房间"。最初的回答如上所示。

4
当使用非默认适配器(例如socket.io-redis)时,socket.rooms似乎无法实现预期功能。我找到的一种不用循环即可获取特定客户端房间的方法是使用io.sockets.adapter.sids[socket.id],它将房间作为一个对象返回。
{ 'R-ZRgSf7h4wfPatcAAAC': true, ROOM: true, ROOM_2: true }

请注意,这并不列出其他进程上的套接字!
socket.io v1.3.7,socket.io-redis 1.0.0

2

确保套接字一次只在一个房间中,我的解决方案是:

var currentRoom = Object.keys(io.sockets.adapter.sids[socket.id]).filter(item => item!=socket.id);

2

Socket.io v2.1.1

请确保您不要在disconnect事件中访问套接字房间,因为它们在触发该事件时已经离开了房间。如果您想要这样做,请尝试在disconnecting事件中进行- https://github.com/socketio/socket.io/pull/2332/files

然后,您可以使用以下任何一个:

Object.keys(socket.adapter.rooms)
Object.keys(socket.adapter.sids)
Object.keys(socket.rooms)

使用这种方法,有没有一种方式可以通过 socket.id 字符串查找套接字所在的房间?即不使用传递给事件的 socket,而只是一个包含 socket.id 的字符串? - user1063287

2

版本1.7.3中,socket.rooms包含socket.id,因此需要将其移除并获取房间列表:

Object.keys(socket.rooms).filter(item => item!=socket.id);

在其他版本中,您可以打印socket并查找房间。

1

版本 2.0.3

io.sockets.sockets[yourSocketID].rooms

那等于
socket.rooms

0

当套接字加入房间时,可以在套接字本身中节省空间

// join room
socket.join(room);

// update socket's rooms
if (socket.rooms) {
    socket.rooms.push(room);
} else {
    socket.rooms = [room];
}

稍后,您可以通过简单地检索套接字所在的所有房间来检索它们。
socket.rooms

来自服务器 API 文档:

socket.rooms (对象)
标识此客户端所在房间的字符串哈希表,以房间名称为索引。

https://socket.io/docs/server-api/#socket-rooms


2
我在想,socket.rooms不是会在每次有 socket 加入房间时自动被 socket.io 更新吗? - user1063287
你绝不能像这样修改API。既然库已经做了这个,为什么还需要更新socket.rooms呢? - Emobe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接