6

Trying to execute the simplest of targeted messaging in socket.io with no success. According to the documentation for socket.io with express.js you can target a message to a single user socket with socket.to(socket.id).emit('event name', 'message')

I have already read the socket.io docs from start to finish and other stack overflow Q/A here and here and here. Some of the solutions I find involve creating rooms and messaging those rooms, but the objective of this question is to send a message to the socket id using socket.to(socket.id).emit('event name', 'message') as given in the socket.io documention.

I'm using node v6.11.2, express 4.15.2 and socket.io 2.0.3.

The client and server code are taken almost verbatim from https://socket.io/get-started/chat/ with minor changes while I experiment.

index.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');

    io.on('connection', function(socket){
        console.log(req.ip+' connected');
        socket.on('chat message', function(msg){
            console.log(socket.id);//logs the socket id. Something like 'AUCyM1tnpinCfvfeAAAB'
            console.log(msg);//logs whatever the message was, so I know the server is receiving the message
            socket.to(socket.id).emit('chat message', 'Nothing is happening here.');
        });
    });
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

index.html

<!doctype html>
<html>
    <head>
        <title>Socket.IO chat</title>
        <style>
          ...
        </style>
    </head>
    <body>
        <ul id="messages"></ul>
        <form action="">
            <input id="m" autocomplete="off" /><button>Send</button>
        </form>
        <script src="/socket.io/socket.io.js"></script>
        <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
        <script>
            $(function () {
                var socket = io();
                $('form').submit(function(){
                    socket.emit('chat message', $('#m').val());
                    $('#m').val('');
                    return false;
                });
                socket.on('chat message', function(msg){
                    $('#messages').append($('<li>').text(msg));
                });
            });
        </script>
    </body>
</html>
Altimus Prime
  • 2,207
  • 2
  • 27
  • 46

2 Answers2

10

Change this:

socket.to(socket.id).emit(...)

to this:

socket.emit(...)

Here's an explanation. socket.to(socket.id).emit(...) will broadcast to the room named socket.id. That's OK, there is a room with that name and socket is the only member. But, socket.to() sends to all members of that room EXCEPT socket so there's nobody to send it to.

So, if you want to send just to socket, then just use socket.emit().

Here's a quote from the socket.io doc for socket.to():

Sets a modifier for a subsequent event emission that the event will only be broadcasted to clients that have joined the given room (the socket itself being excluded).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 3
    I had missed the part of the documentation that .to() excluded the socket, so +1 for sure. If you have some other recommendation to to send messages to a connecting socket, basically a private message from the server to the socket on an event, I'd appreciate it. – Altimus Prime Aug 30 '17 at 10:25
  • The github documentation is much more thorough than the socket.io website. The socket.io website does not explain anywhere near as much as the docs you linked to on github. – Altimus Prime Aug 30 '17 at 10:47
  • @AuntJamaima - The way I've suggested, only the sender gets the message (that's what your code was attempting to do). You only described a problem where the sender did not get the message so I don't know what problem beyond that you're trying to solve. I think I've answered the problem you described. If you have some other problem you also want help with, you will have to describe that (probably in a new question). – jfriend00 Aug 30 '17 at 15:43
  • @AuntJamaima - FYI, if you are trying to send a message to all members of a room, you use `io.to(room).emit(...)` where `io` is your server instance. – jfriend00 Aug 30 '17 at 15:59
  • @AuntJamaima - The socket.io documentation is often lacking in general so I get rather used to actually examining the code on Github to figure out what things actually do. But, yes you are right that, for some things, the Github doc seems to be more complete. – jfriend00 Aug 30 '17 at 16:02
  • @AuntJamaima - Just to be clear here, `socket.emit(...)` sends a PRIVATE message to only the one `socket`. – jfriend00 Aug 30 '17 at 16:04
  • Thank you very much. You're right on. I didn't even realize there were separate `io` and `socket` methods for emit. I misunderstood your answer, but you are spot on. The github documentation really helps a lot because all the methods are documented there. – Altimus Prime Aug 30 '17 at 17:26
8

Change this :

socket.to(socket.id).emit('chat message', 'Your message');

To this :

io.to(socket.id).emit('chat message', 'Your message');

if you want you can check this link : https://socket.io/docs/emit-cheatsheet/

  • thanks this really helped , but can please confirm the exact reason behind it as all other events are working fine over socket instance. – Bhanu Arora Jun 18 '22 at 21:58