Socket.io: Mechanism to add a client to a room with only his ID?

Created on 2 Nov 2014  路  10Comments  路  Source: socketio/socket.io

I see currently it is possible to send a message to a socket because a default room is created with his ID.

However I don't know if it would be possible to add this socket to a room, to remove from a room or just to disconnect it, of course in multi server environment. Any ideas?

Thank you!

enhancement

Most helpful comment

Closed by https://github.com/socketio/socket.io-redis/pull/168.

io.adapter.remoteJoin('<my-id>', 'room1', function (err) {
  if (err) { /* unknown id */ }
  // success
});

io.adapter.remoteLeave('<my-id>', 'room1', function (err) {
  if (err) { /* unknown id */ }
  // success
});

All 10 comments

Wait, what are you asking here?

  • You can add sockets to rooms
  • You can remove sockets from rooms
  • In multi server environments you can broadcast to all clients in rooms using socket.io-redis, but you can't (yet) list them.

I mean, in a multiserver environment, given a socket id string, I can send a message using:

io.to(string_id).emit('hello')

But I cannot do:

io.join(string_id, room)
io.disconnect_socket(string_id)

Because the socket could be in the current server or maybe in other one.

I hope I've explained better.

What I would do is setup a redis pub/sub channel. Make sure all connected sockets (on all servers) listen to this channel. Then send these kind of commands over this channel.
I wrote the following library to make this slightly easier.
https://www.npmjs.org/package/redis-pubsubber

Hello. Thank you for you answer. I see, I could implement it, however I feel like this feature should be implemented by socket.io. Moreover when in the next version you can list the client of a room: https://github.com/Automattic/socket.io/pull/1630

So this is more a feature request if there is not a simple way to do it, a good api to manage clients easily from any server. What do you think?

Need to think about whether we'll add this feature. I can definitely see the usecase.

I think this could be really handy for implementations where you have a lot of publishers and a few subscribers. In that case most rooms are empty so it's a waste to broadcast to all nodes.
I had a cool optimization in 0.9 where I would do:

if(io.of(nsp).clients(room_id).length > 0) {
    io.of(nsp).in(room_id).emit('m', message);
}

But now that a single node does not see the whole list of clients it cannot be done without some pubsub mechanism to make the publisher join the room on command.

Did you find the right solution how to do this in multi-server env?

I really liked @alexcastano 's approach: io.join(socketId, roomId)

Closed by https://github.com/socketio/socket.io-redis/pull/168.

io.adapter.remoteJoin('<my-id>', 'room1', function (err) {
  if (err) { /* unknown id */ }
  // success
});

io.adapter.remoteLeave('<my-id>', 'room1', function (err) {
  if (err) { /* unknown id */ }
  // success
});

can i do this without redis ? @darrachequesne

Was this page helpful?
0 / 5 - 0 ratings