Socket.io: broadcasting to all clients except sender issue

Created on 22 Jun 2016  路  4Comments  路  Source: socketio/socket.io

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.

Most helpful comment

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.

All 4 comments

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

Was this page helpful?
0 / 5 - 0 ratings