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).
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).
Share Improve this question asked Sep 6, 2013 at 9:15 alexandernstalexandernst 15.1k25 gold badges107 silver badges213 bronze badges 4- Thats exactly what rooms are designed for. Do you know a user can be present in multiple rooms at the same time? Chosing between a/b depends on the security level, in case the user isn't pletly forbidden to see the message, b) it's propably easier to acplish and in terms of performance: a client side task you don't have to give a **** about. So I'd go for b). – RienNeVaPlu͢s Commented Sep 6, 2013 at 9:20
- If you absolutely cannot show the msg to the user.. then go for a... if it is ok for the user to see it in the network flow.. than b is probably easier – user1600124 Commented Sep 6, 2013 at 9:24
- Yes, I know that a single client can be in multiple rooms, but here's the thing: I'll have to create as many rooms as clients I have (because I need to send messages to everyone except one different user at a time), and I'm really not sure about the performance of that. On the other hand, the client-side thing looks really durty :( – alexandernst Commented Sep 6, 2013 at 9:24
- Something like this still not being there in 2019 has caused a lot of pain. – iPhoney Commented May 28, 2019 at 7:23
2 Answers
Reset to default 4Rooms - are not the way to acplish 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.
Socket IO already has this feature, just like this:
io.to("room2").except("room3").emit(/* ... */);
or to exclude some certain client (socket):
io.to("room2").except(socket.id).emit(/* ... */);