Bobby Graczyk
Bobby Graczyk

Reputation: 86

Socket.io - io.in(room).emit() not working on rooms joined in callbacks

In my MERN app I have the following code:

Server:

io.on('connection', (socket) => {
  socket.join('main');
  socket.on('start session', function(data){
    socket.join('sockets');
  });
  socket.on('try', () => {
    io.in('main').emit('test', 'hi');
    io.in('sockets').emit('test', 'hello');
    console.dir(socket.rooms);
  })
});

Client:

componentDidMount() {
    socket.on('connect', function(){console.log('connected to socket')});
    socket.on('test', function(data){console.log(data)});
    socket.on('event', function(data){console.log(data)});
    socket.on('error', (error) => {
      console.log(error)
    });
  }
  setSession(id, slug) {
    if(!this.state.sessionId) {
      socket = io(serverUrl);
      this.setState({ sessionId: id, slug: slug });
      let sessionInfo = {room: id, slug: slug};
      console.log(`Session local init. SessionId: ${id}, Slug: ${slug}`);
      socket.emit('start session', sessionInfo);
    }    
  }

In a separate client component I emit the 'try' event when I click a button.

The server console validates that the socket is in both rooms (this is called after we emit the events, so there is no way the socket's rooms are being changed/overwritten)...

{
  ub1_9Nw3sMtfZQtBAAAF: 'ub1_9Nw3sMtfZQtBAAAF',
  main: 'main',
  sockets: 'sockets'
}

...however, the client only receives the event emitted to the 'main' room, and not the 'sockets' room. The server thinks the client is in both rooms and the only difference is that the 'sockets' room assignment is in an event callback and the 'main' room assignment is at the top-level of the 'connection' function. Thoughts?

Upvotes: 1

Views: 1526

Answers (2)

Bobby Graczyk
Bobby Graczyk

Reputation: 86

For now, I've managed to bypass this issue by sending the room name in the query param when the client connects.

Client:

socket = io(serverUrl, {query: {id: id}});

Server:

io.on('connection', (socket) => {
  socket.join(socket.request._query.id);
  socket.on('try', (data) => {
    io.to(data).emit('join', 'bang');
  })
});

...however it still seems as if the original code should have worked - very little else has been modified. Leaving the question up because a workaround isn't a solution and this isn't best practice!

Upvotes: 1

Bahrom
Bahrom

Reputation: 4862

You only join the 'sockets' room if the client emits a 'start session' event.

socket.on('start session', function(data){
    socket.join('sockets');
});

Client only seems to be emitting 'start session' in setSession, and I don't see that method getting called anywhere.

Upvotes: 0

Related Questions