socket.io - how to broadcast messages on a namespace?

JustAMartin picture JustAMartin · Jun 25, 2011 · Viewed 76.8k times · Source

According to socket.io examples:

To broadcast, simply add a broadcast flag to emit and send method calls. Broadcasting means sending a message to everyone else except for the socket that starts it.

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.broadcast.emit('user connected');
});

I tried to combine this with the new socket.io namsepace feature, so I got this:

var chat = ioserver.of('/chat');

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        chat.send(msg);
      });
  });

This works fine, everyone on the chat channel (and no other channels) gets the message. But the sender also gets it. So I tried to do the following:

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        chat.broadcast.send(msg);
      });
  });

and got an Exception: 'Cannot call method 'send' of undefined.' Ok, so I thought, that broadcast is the feature of a single socket (it feels a bit weird though - how a single socket can brodacast to all other...). So I tried:

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        socket.broadcast.send(msg);
      });
  });

but now it was even worse - no one received the message, not even the sender. Anyway, it was what I logically expected - one socket cannot broadcast something through itself. And no exceptions this time, so broadcast is defined for the socket.

If I do:

chat.on('connection', function (socket) {
      console.log('chat connection');   
      socket.on('message', function (msg) {
        console.log(msg);  
        socket.send(msg);
      });
  });

then only the original sender gets the message, and that is again pretty logical - I used the 'send' of the client-related socket.

So the question is: what is the correct way to use the broadcast feature?

Maybe the developer of socket.io made a mistake and added the broadcast feature to the wrong object (as I understand, it should be the feature of the namespace but now it is defined only for the socket)?

Answer

Michael picture Michael · Jul 16, 2011

Seems I was able to solve this for myself after opening a bounty. Sorry about that.

Anyway, see if this helps:

chat.on('connection', function (socket) {
  socket.on('message', function (msg) {
    socket.emit(msg); // Send message to sender
    socket.broadcast.emit(msg); // Send message to everyone BUT sender
  });
});

However, you could save some bandwidth and create a more snappy experience for users if you don't resend it to the sender. Just add their messages directly to the chat log, and optionally use use only self-emit to confirm it was received without issue.