繁体   English   中英

循环遍历唯一的 Socket.IO 房间以向 NodeJS 中的每个房间发送唯一数据

[英]Loop over unique Socket.IO rooms to emit unique data to each room in NodeJS

我通过允许客户传递他们的房间名称来创建房间:

io.on('connection', socket => {
  socket.join(socket.handshake.query.roomName)
})

假设三个套接字连接,房间名称为 1、2 和 3。我希望能够执行以下操作:

listOfRooms.forEach(sendSomeData)

sendSomeData(room, index){
    let data = getSomeData(room)
    io.in(room).emit('data', data)
}

其中getSomeData(room)根据传递给它的房间的名称生成不同的数据。

是否有任何内置方法可以在不设置数据结构来管理它的情况下获取根命名空间或该 IO 实例中所有房间的列表?

是的,我可以在每次发生新连接时创建一个数组并附加到它,但是如果两个套接字加入同一个房间,似乎需要很多额外的工作来管理,我不希望我的数组有重复,但我可以当一个套接字断开连接时,不能同时删除重复项并从数组中删除对象...

您可能不想发送到命名空间中所有房间的列表,因为 socket.io 为每个连接的用户创建了一个房间,而您不想发送给所有这些用户。

您可以获得一个包含命名空间中所有房间的对象(作为对象的属性名称),如下所示:

let roomsObject = io.of("/").adapter.rooms

或者,像这样获得所有房间:

let allRooms = Object.keys(io.of("/").adapter.rooms);

所以,那么你只需要能够分辨哪些房间是你添加的,哪些是 socket.io 为每个连接的套接字自动添加的。 我能想到的最简单的方法是始终在您创建的任何房间的开头添加一些标记字符,例如下划线。

io.on('connection', socket => {
  socket.join("_" + socket.handshake.query.roomName)
});

而且,当然,在您提到房间名称的任何其他地方,您需要确保其前面有适当的“_”,或者如果您向用户显示房间名称,则需要将其删除。

然后,您可以分辨房间名称和 socket.io 房间名称之间的区别:

let myRooms = Object.keys(io.of("/").adapter.rooms).filter(room => room.startsWith("_"));

现在,您可以迭代该房间列表:

for (let room of myRooms) {
    io.of("/").to(room).emit(...)
}

注意:在这个答案中,我展示了io.of("/")来指示您如何指定要使用的命名空间(因为您明确提到了命名空间对象),但是如果您只是使用默认命名空间,则可以只是到io.to("room").emit(...)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM