Socket.io: socket.rooms 是一个无用的对象

创建于 2017-03-08  ·  8评论  ·  资料来源: socketio/socket.io

这与socket.rooms对象有关,记录为:

标识此客户端所在房间的字符串散列,按房间名称索引。

我不知道那是什么意思,但例子很清楚:

io.on('connection', function(socket){
  socket.join('room 237', function(){
    console.log(socket.rooms); // [ <socket.id>, 'room 237' ]
    io.to('room 237', 'a new user has joined the room'); // broadcast to everyone in the room
  });
});

当我运行console.log(socket.rooms); ,我_想要_那个漂亮的数组(这样我就可以切掉并且只得到房间),但我得到了这个丑陋的对象:

io.on('connection', function(socket){
  socket.join('room 237', function(){
    console.log(socket.rooms); // { <socket.id>: '<socket.id>', 'room 237': 'room 237' }
  });
});

...然后我必须用.keys()变成一个数组,然后手动挑选socket.id (因为它可能不是第一个)。

这是一个错误吗? 我正在使用 1.7.3。

最有用的评论

是的,这似乎不必要地复杂。 我真的很难理解为什么用户的套接字 id 构成一个“房间”?,或者为什么需要key:value对。 它只需要是一个列表 - 无论房间存在,您都在,完成。

['room1', 'room2', 'room3']

和上面一样, io.rooms 可以将它们全部获取,也可以作为字符串数组,或者在这种情况下作为以房间名称作为键和套接字 id 数组作为其值的对象。

{ room1: ['id1', 'id2', 'id3'], room2: ['id4', 'id5', 'id6'] }

所有8条评论

好吧,这里的文档似乎不是最新的,我认为rooms在 v1.4 之前实际上是一个数组。

注意:我想我们可以使用布尔值作为值。

我想这是一个功能请求。 让 socket.io 再次伟大:带回数组!

我的目标是获取客户所在的房间数组。对于数组,我假设socket.id将是第一个:

var rooms = socket.rooms.slice(1);

使用当前的实现:

var roomKeys = Object.keys(socket.rooms);
var socketIdIndex = roomKeys.indexOf( socket.id );
var rooms = roomKeys.splice( socketIdIndex, 1 );

如果不包括socket.id也没关系。 我只是不想必须找到它并挑选出来。

var rooms = Object.keys(socket.rooms);

使用布尔值,我将能够过滤掉真正的值,就像这样(对吗?):

var roomKeys = Object.keys(socket.rooms);
var rooms = roomKeys.filter(function(key){ 
  return socket.rooms[key]==true;
});

这与使用indexOf()迭代一样慢。

包含客户端不在的房间(例如显示它可以加入的聊天室)会很有帮助。 我只是认为其他地方的信息会更好,比如Server实例:

var allRooms = io.rooms;
var myRooms = socket.rooms;

还有人对此有意见吗?

是的,这似乎不必要地复杂。 我真的很难理解为什么用户的套接字 id 构成一个“房间”?,或者为什么需要key:value对。 它只需要是一个列表 - 无论房间存在,您都在,完成。

['room1', 'room2', 'room3']

和上面一样, io.rooms 可以将它们全部获取,也可以作为字符串数组,或者在这种情况下作为以房间名称作为键和套接字 id 数组作为其值的对象。

{ room1: ['id1', 'id2', 'id3'], room2: ['id4', 'id5', 'id6'] }

我认为主要原因是查找性能。
例如,当用户加入 100 个房间时,使用对象查找来确定他是否加入了一个房间而不是迭代数组值会更快。

参考我在stackoverflow上的回答

{
    "room1":"room1",
    "room2":"room2",
    ...
    "room100":"room100"
}

要检查用户是否加入了一个房间,就像这样简单:
if(socket.rooms[roomID]) return true;

如果它是数组类型,那么我们需要使用 indexOf 或迭代每个数组:
if(socket.rooms.indexOf(roomID) != -1) return true;

但我完全同意,如果键值更改为布尔值:
{ room1: true, ... , room100: true }

它可能有助于节省一些内存使用量

我不介意更改 socket.rooms 以便值是布尔值。 做这件事可以吗? 我不确定贡献过程是什么,因为我没有看到 CONTRIBUTING.md 文件。

Set不是更有意义吗?

if (socket.rooms.has(roomID)) return true;

例如,结构将是简单的Set(4) {"<socket ID>", "room1", "room2", "room3"}

只要集合的时间复杂度是恒定的,我就同意。 我相信 javascript。

在 Socket.IO v3 中, Socket#rooms现在将是一个 Set,并使用底层适配器提供的值,请参见此处

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

thebinarypenguin picture thebinarypenguin  ·  4评论

Aweather picture Aweather  ·  4评论

MyMomSaysIAmSpecial picture MyMomSaysIAmSpecial  ·  4评论

varHarrie picture varHarrie  ·  3评论

karmac2015 picture karmac2015  ·  3评论