Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 620
user1032369 Avatar asked Oct 30 '25 18:10

user1032369


1 Answers

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);
});
like image 145
Vitali Kotik Avatar answered Nov 01 '25 08:11

Vitali Kotik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!