简体   繁体   中英

Socket.io won't emit to a room

I am trying to create a chat lobby where users can create a private room, and others can join through a uuid. This is built with node.js and socket.io, and it seems as if io.to(room).emit('event', 'data') and io.sockets.to(room).emit('event', 'data') do not work , while io.emit('event', 'data') works. My code can be found below:

io.sockets.on('connection', (socket) => {
  socket.on('createRoom', function(data) {
      let room = new Room(data).create();

      let id = room.data.uuid
      socket.join(id)

      io.to(id).emit('roomcreated', {data: data, msg: 'Room Created'}) //Does not work!
      io.emit('roomcreated', {data: data, msg: 'Room Created'}) //This Works
  });
});

A common problem with .join() is that it is actually asynchronous. It does not immediately complete. This is probably because it's designed to work with the multiple process, redis-based adapter that supports clustering and there the join process has to be asynchronous because it's communicating with other processes.

You can fix your issue, by sending a callback to .join() and only emitting to the room AFTER it has finished joining.

io.sockets.on('connection', (socket) => {
  socket.on('createRoom', function(data) {
      let room = new Room(data).create();

      let id = room.data.uuid
      socket.join(id, (err) => {
         if (err) {
             // do something here if the join fails
             console.log(err);
             return;
         }
         
         // call this only after the join has completed
         io.to(id).emit('roomcreated', {data: data, msg: 'Room Created'});
      });
  });
});

I'm not sure entirely what's not working with io.in(id).emit('roomCreated', {d: data}); but I found a work around method.

I created an object of all sockets called SOCKET_LIST, and an array for each room that holds the id of that socket:

var SOCKET_LIST = {};

io.sockets.on('connection', (socket) => {

  socket.id = Math.random();
  SOCKET_LIST[socket.id] = socket;

  socket.on('createRoom', function(data) {
      let room = new Room(data).create();
      room.data.users.push(socket.id)

      let id = room.data.uuid
      socket.join(id, (err) => {
        if(err) {
          return console.log(err);
        }
        room.data.users.forEach(i => {
          SOCKET_LIST[i].emit('roomcreated', {data: data, msg: 'Room Created'})
        })
      })

  });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM