Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emiting with exclusion in Socket.io

Is there a way to emit a message via socket.io while excluding some socket id? I know about the existence of rooms, but that's a no-no for me.

If what I'm trying is impossible, what should I do between those two things:

a) Iterate over all users that I want to send a message (in fact, all of them except 1) and do a emit for each socket

or

b) Just emit the message to everyone and do something hacky on the client side to "ignore" the message.

EDIT: I can't do a broadcast because the message is generated from the server side (so there is no client interaction).

like image 501
alexandernst Avatar asked Oct 04 '22 01:10

alexandernst


1 Answers

Rooms - are not the way to accomplish of what you are trying to do, as they are meant to be used only to limit groups of people, but not specific.

What you are looking for is simple collection of users and ability to set some sort of filter on them. Iteration through list of sockets - is not that critical, as when you broadcast - it does iteration anyway.

So here is small class that keeps sockets, removes them when needed (disconnect) and sends message to all with optional exception of single socket.

function Sockets() {
  this.list = [ ];
}
Sockets.prototype.add = function(socket) {
  this.list.push(socket);

  var self = this;
  socket.on('disconnect', function() {
    self.remove(socket);
  });
}
Sockets.prototype.remove = function(socket) {
  var i = this.list.indexOf(socket);
  if (i != -1) {
    this.list.splice(i, 1);
  }
}
Sockets.prototype.emit = function(name, data, except) {
  var i = this.list.length;
  while(i--) {
    if (this.list[i] != except) {
      this.list[i].emit(name, data)
    }
  }
}

Here is example of usage, user sends 'post' message with some data, and server just sends it to all in collection except of original sender:

var collection = new Sockets();

io.on('connection', function(socket) {
  collection.add(socket);

  socket.on('post', function(data) {
    collection.emit('post', data, socket);
  });
});

In fact it can be used as rooms as well.

like image 59
moka Avatar answered Oct 13 '22 10:10

moka