簡體   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