The Socket.io documentation seems to specify a few ways to emit an event to all connected clients in a room. They are as follows:
io.to()
, as found in the first example here: https://socket.io/docs/server-api/#socket-join-room-callback
io.in()
, as found in the emit cheatsheet, found here: https://socket.io/docs/emit-cheatsheet/
socket.to()
, as found here: https://socket.io/docs/server-api/#socket-to-room
Other than the examples linked above, both io.to()
and io.in()
are not listed anywhere else in the documentation. What do these methods do exactly, and where can I find more information on them?
socket.to()
can be used inside the io.on('connection', callback)
event, like so:
io.on('connection', function(socket){
// to one room
socket.to('others').emit('an event', { some: 'data' });
// to multiple rooms
socket.to('room1').to('room2').emit('hello');
});
However, this does not make sense, as the socket
object passed into this callback represents a connected client. How can the incoming socket object be used to broadcast to all other connected sockets, as shown in the above example?
Definitive explanations of the above are appreciated.
Simply said Each socket emits its msg to a server(io is an instance of server) and server, in turn, emits it to all connected sockets.
In your code example, io is a Socket.IO server instance attached to an instance of http. Server listening for incoming events. The socket argument of the connection event listener callback function is an object that represents an incoming socket connection from a client.
socket.io rooms are a lightweight data structure. They are simply an array of connections that are associated with that room. You can have as many as you want (within normal memory usage limits). There is no heavyweight thing that makes a room expensive in terms of resources.
However, this does not make sense, as the socket object passed into this callback represents a connected client.
If you trace into those call in a debugger, you can see what is going on.
First off, the socket.to()
creates a property on the socket named _rooms
that is an array of room names. You can see the whole code in context here in the Github repository, but here's the relevant portion for .to()
:
Socket.prototype.to =
Socket.prototype.in = function(name){
if (!~this._rooms.indexOf(name)) this._rooms.push(name);
return this;
};
Each successive call to .to()
just an addition room to the array.
Then, socket.emit()
checks to see if the _rooms
property exists and if it does, it calls this.adapter.broadcast(...)
which grabs the adapter and tells it to broadcast this message to all sockets on that adapter except the current one. The whole code for socket.emit()
is here on Github. The particular broadcast part of the code is this:
if (this._rooms.length || this.flags.broadcast) {
this.adapter.broadcast(packet, {
except: [this.id],
rooms: this._rooms,
flags: this.flags
});
} else {
// dispatch packet
this.packet(packet, this.flags);
}
How can the incoming socket object be used to broadcast to all other connected sockets, as shown in the above example?
Each socket contains a reference to the adapter and the adapter has a list of all sockets on that adapter. So, it's possible to get form the socket to the adapter, to all the other sockets.
I would agree that this is a bit of an odd overloading of functionality, but that's how they do it. I'm guessing they wanted to give people access to broadcast functionality when all you had a reference to was an individual socket.
FYI, the only way to really answer these types of questions yourself that are not documented is by looking at the code and that is certainly one of the huge advantages of using open source libraries. I find that the quickest way to get to the right source is to step into the method of interest in the debugger. Fire up the debugger, set a breakpoint in your code, then step into the function of choice and it will show you the relevant source code immediately. You can then further step through that function if you want to see what path it is taking.
For anyone coming across this question like me, here is the link to the docs for explanation: https://socket.io/docs/v3/rooms/index.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With