I have a node.js server that's using Socket.io to emit events to clients. When a connection event occurs, the new socket is placed in a room based on the connecting user's id, which is obtained using the session id cookie from socket.headers.handshake.cookie
. I know this part is working, because I can set a breakpoint and inspect io.sockets.adapter.rooms
and see this room:
So, the room apparently has only one socket in it. Also while paused at this breakpoint, the following expression: userID.toString()
evaluates to: "5cd6201acb0d5f23e465cb84"
. So, this expression should be usable to obtain the room with that one socket in it. Then, directly after the breakpoint, this code executes:
io.of('/').in(userID.toString()).emit('notification', notifHTML);
So, I would expect the notification event to only be emitted to the one socket in that room identified by that expression. The notification event is handled by the client thusly:
socket.on('notification', function(notifHTML){
$("#notificationsContainer").prepend(notifHTML);
$(".notifications-count").html('<i class="fas fa-dot-circle"></i>');
document.title = '(⚐) sweet';
});
However, as it turns out, every client connected to the server recieves that notification event and handles it in the above-shown way; when I have three browsers connected to the server, all three of them execute the above code; I can see the results on the page and in the new document title.
I actually can fix this by replacing that line that has .to with the following:
io.of('/').in(userID.toString()).clients(async (error, clients) => {
for (var client of clients) {
io.sockets.connected[client].emit('notification', notifHTML);
}
})
Then, the event is only emitted to the client I want it to be, the one in the room that I showed. (This room could contain multiple clients if one user connects to the server from multiple browsers, so I can't replace this room code with code to target a single socket.) However, the code shouldn't need to be this verbose; I would still like to know why .to is not working the way I expect it to. As far as I can tell from reading the docs, it should provide that same functionality of only emitting events to the sockets in a specified room.
In order to emit
events to all the sockets
in a particular room, try doing...
io.sockets.in('my-room').emit('my-event', someData);
...this will broadcast
the event
to all sockets
in that room in the default namespace. You can use of('my-namespace')
with io
to specify the namespace as well. You are missing the sockets
part after io
in your code.
Alternatively, doing...
socket.broadcast.to('my-room').emit('my-event', someData);
...will broadcast
the event
to all the sockets
in that room except the one broadcasting.
Hope this helps :)
使用.to
代替.in
io.of('/').to(userID.toString()).emit('notification', notifHTML);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.