I've noticed this weird behavior while broadcasting to other clients using socket.broadcast.emit()
Here's the sample code of the problem:
...notifyOtherClients = function(room, e, data, socket)
{
// sending to all clients in a room except sender
var transport = socket.broadcast.to(room);
//
setTimeout(function(){
// #method1: this works as expected: all clients receive event except the sender
socket.broadcast.to(room).emit(e, data);
// #method2: this doesn't work though: all clients receive this event. Why?! Bug?
transport.emit(e, data);
// logs out 'true'
console.log(transport === socket.broadcast.to(room));
},
1000);
};
...
notifyOtherClients("myRoom", "someEvent", { }, socket);
What am i missing here? Why #method2 doesn't work as expected.
Thanks.
What's returns from socket.broadcast.to(room)
?
@Mad-Head According to docs, returns the same socket instance almost like all other method to keep the chainability.
http://socket.io/docs/server-api/#socket#to(room:string):socket
The funny thing is that this traces true
console.log(transport === socket.broadcast.to(room));
Hi! socket.broadcast
actually add a temporary flag (namely, broadcast
) which will be used the next time emit
is called on the socket
.
The flag is used the first time, and then is deleted, hence the result of your second call.
Hi there! Hm... maybe i wasn't clear enough. Let me make it more obvious:
sample1
setTimeout(function(){
// #method1: this works as expected: all clients receive event except the sender
socket.broadcast.to(room).emit(e, data);
},
1000);
sample2
var transport = socket.broadcast.to(room);
setTimeout(function(){
// #method2: this doesn't work though: all clients receive this event. Why?! Bug?
transport.emit(e, data);
},
1000);
So it's not flag related. The two samples above should work the same, but they don't. That's the problem and i've been beating up against the wall for like 1/2 a day to figure out why.
UPD: actually @darrachequesne you are right. I've looked into the source: everytime emit() is called _rooms get flushed and the weird problem occured as while the setTimeout was still in progress another method called emit() and flushed the room (ping was the problem)
that's what happened
1. setup a room with to()
2. start timeout for 1000 ms
...
[some where between 0 and 1000 ms] ping occurs i.e. emit() and flushes the room
...
3. timeout calls socket but the room's already flushed.
4. *problemo* all clients get notified including the sender socket.
Thanks a lot for your suggestion @darrachequesne.
Closing this one
Most helpful comment
Hi!
socket.broadcast
actually add a temporary flag (namely,broadcast
) which will be used the next timeemit
is called on thesocket
.The flag is used the first time, and then is deleted, hence the result of your second call.