55

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)?

JustAMartin
  • 13,165
  • 18
  • 99
  • 183

4 Answers4

75

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.

  • 11
    and if you use `io.sockets.emit('signal', obj)` sends the signal to everyone – orloxx Dec 03 '12 at 19:32
  • This example should be near the top of the Socket.IO docs. Most applications need to reply to each connection independently, rather than always broadcast to all listeners unconditionally! – Cuadue Sep 16 '14 at 16:38
  • Using this code you emit the message to all the sockets in the namespace and not only to the sockets of a particular room. Am I right? – Dejan Bogatinovski Apr 14 '15 at 22:25
  • 3
    I don't understand. You said in the question that this exact code, minus `socket.emit(msg);`, caused **no one** to receive the message. Why does adding `socket.emit(msg);` suddenly cause `socket.broadcast.emit(msg);` to send the message to everyone but the sender? – BlueRaja - Danny Pflughoeft Aug 05 '15 at 13:46
38

You solution works if you are working in an evented environment where messages from the client trigger a response to all others, but not if you want the server to sent messages to all clients.

You can do this using io.sockets.emit:

var io = require('socket.io').listen(80);
io.sockets.emit('message', { message: "Hello everyone!" });

However the documentation isn't clear for how to do this to a specific namespace. io.sockets is just a shortcut to io.of(''), as such you can broadcast to everyone on a namespace by calling io.of('/namespace').emit:

var io = require('socket.io').listen(80);
io.of('/admins').emit('message', { message: "Hello admins!" });
Luca Spiller
  • 2,248
  • 4
  • 24
  • 28
  • 2
    To me this sounded a bit like mixed up the terms of `namespace` and `room` for sockets. Which are treated separately. For those who look for broadcasting to a specific room (from server) the syntax would be `io.sockets.in('room name').emit` – Kirill Slatin Apr 13 '15 at 11:06
  • I don't understand how this answers the question... The question is how to *broadcast* a message, your answer sends message to everyone which already works in OPs code – T J Dec 30 '15 at 14:02
  • Just as an update - a server emitting to all the clients till isn't specific in the Docs. You'll figure it out when you play with it but it's not readily intuitive how to use < insert(io,namespace,socket) here>.emit. Their docs really need to add more examples so it clicks. – Nick Pineda Jan 25 '16 at 06:13
  • saved me big time here! 'sockets' vs io.of() – DanR Oct 27 '16 at 20:54
33
var customNS = ioserver.of('/chat'); 

customNS.on('connection', function (socket) {
   socket.on('message', function (msg) {

       // Send message to sender 
       socket.emit(msg);

       // Send message to everyone on customNS INCLUDING sender
       customNS.emit(msg);

       // Send message to everyone on customNS BUT sender
       socket.broadcast.emit(msg);

       // Send message to everyone on ROOM chanel of customNS INCLUDING sender
       customNS.in('ROOM').emit(msg); 

       // Send message to everyone on ROOM chanel of customNS BUT sender
       socket.broadcast.in('ROOM').emit(msg); 


   });
});

also check this answer Send response to all clients except sender (Socket.io)

Community
  • 1
  • 1
smbeiragh
  • 691
  • 7
  • 6
14

Maybe this will help someone

socket.broadcast.to('room1').emit('updatechat', 'SERVER', username + ' has connected to this room'); 

see

Nodejs and Socketio Multiroom Chat Tutorial

T J
  • 42,762
  • 13
  • 83
  • 138
Shimon Doodkin
  • 4,310
  • 34
  • 37