简体   繁体   English

Socket.io - io.in(room).emit() 不适用于加入回调的房间

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

In my MERN app I have the following code:在我的 MERN 应用程序中,我有以下代码:

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.在一个单独的客户端组件中,当我单击一个按钮时,我会发出 'try' 事件。

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?想法?

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!将问题搁置一旁,因为解决方法不是解决方案,这也不是最佳实践!

You only join the 'sockets' room if the client emits a 'start session' event.如果客户端发出'start session'事件,您只能加入'sockets'房间。

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.客户端似乎只在setSession发出'start session' ,我没有看到该方法在任何地方被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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