Node.js - Socket.io io.emit() doing nothing

10,009

Solution 1

Sockets belong to a certain namespace.

By writing io.of('/projects/test_cases').on('connection', function(socket){}); you put all connected sockets to '/projects/test_cases' namespace.

By writing

 io.sockets.emit("test_case_changed", "test1");
 io.emit("test_case_changed", "test2");

you emit to a default namespace '/' that is different from '/projects/test_cases'

You can easily see the namespace used:

console.log(io.sockets.name) // '/'
console.log(io.of('/projects/test_cases').name) // '/projects/test_cases'

You may want to explicitly specify namespace of sockets to emit messages to

io.of('/projects/test_cases').emit("test_case_changed", "test1");

UPD: As for the second part of the question you may want to know that join is an asynchronous operation. That's why room1 is not in socket.rooms right the next line of code. You may get notified when the socket is in the room using the following lines:

socket.join("room1", function(err){
    console.log("After join: ", socket.rooms);
});

Solution 2

This worked for me. It is sending a message called 'Event' to all the connected sockets once another socket is connected.

I've just removed the unused code, so try doing that first and start from scratch.

Also, the documentation work for me is not that bad.. http://socket.io/docs/ and for namespaces specific http://socket.io/docs/rooms-and-namespaces/

APP.JS

var server = require('http').createServer();
var io = require('socket.io')(server);
var port = 8080;

var nsp = io.of('/projects/test_cases');
nsp.on('connection', function(socket) {
    console.log('someone Connected!');
    nsp.emit('event', 'data');
});

server.listen(port, function(){});

index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script>
    var socket = io('http://localhost:8080/projects/test_cases');
    socket.on('error', function (reason){
        console.error('Unable to connect Socket.IO', reason);
    });
    socket.on('connect', function (){
        console.info('Connected');
    });
    socket.on("event", function (data){
        console.log(data);
    });
</script>
</body>
</html>

To test it open in 3 or 4 tabs the index.html file and just press refresh 5 or 6 times on one of it, then check the console for the other tabs.. it should be logged 'data' a couple of times.

Share:
10,009
user1032369
Author by

user1032369

Herp-di-Derp, Derp, Derp.

Updated on August 01, 2022

Comments

  • user1032369
    user1032369 almost 2 years

    I'm having a problem with my socket.io applicaiton, the io.emit(), and io.sockets.emit() straight up do not work, they do nothing, and return no error.

    I've provided here the most simplified version of the code I can make here.

    Server:

    var server = require('http').createServer();
    var io = require('socket.io')(server);
    var port = 8080;
    
    io.use(function(socket, next){
      next();
    });
    
    io.of('/projects/test_cases').on('connection', function(socket){
      io.sockets.emit("test_case_changed", "test1"); // Doesn't do anything
      io.emit("test_case_changed", "test2"); // Doesn't do anything
      socket.emit("test_case_changed", "test3"); // Works
      io.to(socket.id).emit("test_case_changed", "test4"); // doesn't work
    
    });
    
    io.on('connection', function(socket){
      socket.on('disconnect', function(){
    
      });
    });
    
    server.listen(port, function(){
      console.log('listening on *:' + port);
      setTimeout(function(){
        io.sockets.emit("test_case_changed", "test"); // does nothing
        io.emit("test_case_changed", "test"); // does nothing
      }, 3000);
    });
    

    Client:

    <script>
        var socket = io('http://localhost:8080/projects/test_cases');
        socket.on('error', function (reason){
          console.error('Unable to connect Socket.IO', reason);
        });
        socket.on('connect', function (){
          console.info('Connected');
        });
        socket.on("test_case_changed", function (data){
          console.log(data);
        });
    </script>
    

    As you can see, on the client side test1, test2, test3, and test4 should all print on the client, but only test3 does.

    In addition, if you add the following to the on('connection') method

      console.log("Pre join: ", socket.rooms); 
      socket.join("room1"); // Doesn't work
      console.log("After join: ", socket.rooms); 
    

    That does not work either. IE you can't make the socket join a room in that method.

    • agconti
      agconti almost 9 years
      isn't io.sockets an array of the connected sockets?
    • jfriend00
      jfriend00 almost 9 years
      @agconti - it's an object with some methods. A very confusing and mostly undocumented interface in socket.io. Great library, horrible documentation.
    • user1032369
      user1032369 almost 9 years
      @agconti It is an object. That line does not return any undefined method error, or any error at all, and I have seen it in other people's implementations, so I believe it is a valid call.
    • agconti
      agconti almost 9 years
      @jfriend00 ahh thanks for clearing that up.
    • agconti
      agconti almost 9 years
      @jfriend00 its how you mount socket.io middleware. its only available in the source.
    • user1032369
      user1032369 almost 9 years
      @jfriend00 io.use() is an authentication method. Read about it here: socket.io/docs/migrating-from-0-9
    • jfriend00
      jfriend00 almost 9 years
      OK, thx. Further proof the socket.io doc sucks. It's not documented on the server API page, yet it's clearly meant to be part of the server API. Weird.
    • user1032369
      user1032369 almost 9 years
      @jfriend00 Yeah their documentation is brutally bad. Anyway, removing that has no effect on the bug, so that is not the culrpit.
  • user1032369
    user1032369 almost 9 years
    Alright so this solved part 1 of my question. I was under the assumption that io.emit broadcasted to all namespaces. What do you think about the second part? Where socket.join() isn't working?
  • user1032369
    user1032369 almost 9 years
    Nevermind, socket.join() DOES work, but socket.rooms does not change. I assumed that that listed all current rooms of the socket, but it did not include the new room. However, doing nsp.to("room1").emit() did work. Thanks for the help!
  • user1032369
    user1032369 almost 9 years
    @ecarrizo Never said the developers suck, they are clearly very talented, just that the documentation sucks. I would never have run into this problem if there was a description of the functionality of each function available online. The problems I had were that I was not aware that io.emit only emits to the '/' namespace, and that socket.rooms does not list the rooms that that socket is connected to. If there was documentation which explained what these functions did, I would not have run into the problems. The docs that are there, which are just basic tutorials, do not give these details.