Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences between io.to(), io.in(), and socket.to() for emitting to all clients in a room

Tags:

socket.io

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.

like image 545
Orbit Avatar asked Mar 23 '17 22:03

Orbit


People also ask

What is difference between socket emit and io emit?

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.

What is the difference between io and socket?

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.

How many rooms can Socket.IO handle?

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.


2 Answers

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.

like image 74
jfriend00 Avatar answered Sep 29 '22 12:09

jfriend00


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

like image 27
Daan Avatar answered Sep 29 '22 11:09

Daan