77

I'm new to socket.io and have run in to something that seems pretty weird. I don't actually know the difference between socket.emit and io.emit but I can't find an explanation anywhere.

io.on('connection', function(socket){
  io.emit('connected')  // <<<< HERE >> socket.emit('connected');
  socket.on('disconnect', function(){
    io.emit('disconnect')
  });
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

server.listen(3000);

That's my server stuff however when I change the io to socket that message only gets displayed when the user who is connecting connects. io.emit sends the message to all users.

Maybe it's supposed to be like that or maybe its just some horrible hack? Let me know if you need the client side HTML.

halfer
  • 19,824
  • 17
  • 99
  • 186
Manu Masson
  • 1,667
  • 3
  • 18
  • 37
  • It looks like when the io is connected to it creates a socket just for the current users connection. Picture it as a tree where io is at the top and branches off into several sockets. – keji Sep 20 '15 at 03:24

4 Answers4

202

Here's a supplementary documentation for reference :

socket.emit('message', "this is a test"); //sending to sender-client only

socket.broadcast.emit('message', "this is a test"); //sending to all clients except sender

socket.broadcast.to('game').emit('message', 'nice game'); //sending to all clients in 'game' room(channel) except sender

socket.to('game').emit('message', 'enjoy the game'); //sending to sender client, only if they are in 'game' room(channel)

socket.broadcast.to(socketid).emit('message', 'for your eyes only'); //sending to individual socketid

io.emit('message', "this is a test"); //sending to all clients, include sender

io.in('game').emit('message', 'cool game'); //sending to all clients in 'game' room(channel), include sender

io.of('myNamespace').emit('message', 'gg'); //sending to all clients in namespace 'myNamespace', include sender

socket.emit(); //send to all connected clients

socket.broadcast.emit(); //send to all connected clients except the one that sent the message

socket.on(); //event listener, can be called on client to execute on server

io.sockets.socket(); //for emiting to specific clients

io.sockets.emit(); //send to all connected clients (same as socket.emit)

io.sockets.on() ; //initial connection from a client.

Edit: socket.io docs also contain similar cheatsheet.

starball
  • 20,030
  • 7
  • 43
  • 238
Kent Aguilar
  • 5,048
  • 1
  • 33
  • 20
  • 18
    at the first line you told socket.emit means sending to sender-client only but in the 9th line you told socket.emit(); //send to all connected clients !!! I don't understand! – Unicornist Dec 11 '17 at 08:46
  • 1
    Actually it depends on the need. For instance, on your server you have this line -> socket.emit('message', 'initial message');. This fires up upon script loading. So initially, all connected clients that listen to "message" will display the "initial message" line. – Kent Aguilar Dec 11 '17 at 20:09
  • However, when you have this snippet on your server -> socket.on('message-from-page1', function(message){ socket.emit("message", "response for page 1"); }); and say a client sends a socket.emit('message-from-page1', 'hi from page 1'); and the client also listens to "message", then only that particular client will receive the "response for page 1" line. – Kent Aguilar Dec 11 '17 at 20:09
  • I created a sample for this(though not sure how to share here and simulate), Ping me up so I could quickly demo it. I'll gladly share the code as well. – Kent Aguilar Dec 11 '17 at 20:10
  • Thanks, I get your point now. but it's better to not say `socket.emit(); // send to all connected clients` because the sample you gave for the `"initial message"` is not initiated from a single source of code run for example if you send `socket.emit("initial message"+random)`, everybody gets a different initial message, but for actual broadcasts everybody should get the same number... – Unicornist Dec 12 '17 at 05:16
  • Hey @KentAguilar can you please share the demo with me? – prak Dec 16 '19 at 18:04
43

The io variable represents the group of sockets. The code you have starts on line one with providing a function in the second parameter that gives you a socket variable every time a new connection is made. The socket variable is only for communicating with each individual connection. You may not see it in the code but there will be one socket variable for each connection established

keji
  • 5,947
  • 3
  • 31
  • 47
  • great answer on this... question: so in my Node.js server side code, when I have multiple clients connected via socket.io, and need to send the same data (JSON) out to all clients, if I do io.emit vs socket.emit, is it more efficient and better way to emit? – tamak Oct 12 '16 at 01:13
15
  • socket.emit will send back message to sender only,
  • io.emit will send message to all the client including sender
  • if you want to send message to all but not back to sender then socket.broadcast.emit
1

That's a good question. Here is a sample code that might answer your question.

server.js code:

// Listener for incoming Socket connections

io.on('connection', function(socket){
  socket.on('send', function(msg){
    console.log('message received/sending: ' + msg);
    io.sockets.emit('new', msg);
  });
});

index.html code

<body>
    <ul id="messages"></ul>
    <form action="">
        <input id="m" autocomplete="off" />
        <button type="submit">Send</button>
    </form>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
    <script>
        var socket = io();
        function send(msg) {
            console.log("emitting: " + msg);
            socket.emit('send', { "message": msg });
        }

        socket.on('new', function (msg) {
            console.log("msg " + msg.message);
            $('#messages').append($('<li>').text(msg.message));
        });

        $(function () {
            $('form').submit(function (e) {
                e.preventDefault();
                send($('#m').val());
                $('#m').val('');
                return false;
            });
        });
    </script>
</body>

In index.html socket.emit('send', { "message": msg }); this line of code actually sends/emits message to server which is waiting to listen on socket.on('send', function(msg){ this line of code in server.js.

Now io.sockets.emit('new', msg); this line from server.js emits that message to all its sockets and is displayed to users using its listener in index.html that is socket.on('new', function (msg) {.

Simply said Each socket emits its msg to a server(io is an instance of server) and server, in turn, emits it to all connected sockets. That is how msg sent by any user is displayed to all users. I hope it helps!

Shaishav Jogani
  • 2,111
  • 3
  • 23
  • 33
Shama
  • 11
  • 2