【问题标题】:Socket emits multiple events for each room client connects toSocket 为每个连接到的房间客户端发出多个事件
【发布时间】:2020-07-20 04:35:51
【问题描述】:

我的 react-native 组件正在接收它连接到的每个先前房间的套接字事件。

我有一个简单的组件,它在挂载时会尝试加入套接字房间,而当其他人加入房间时,它会尝试获取最新的房间数据。

当我第一次加载大厅时,我可以很好地加入房间,服务器会发出一个事件说“updateRoom”,每个连接的客户端都会收到该事件并调用更新方法。

如果我返回一个屏幕,然后返回大厅加入一个新房间,我会收到 2 个新成员已加入的事件。 1 似乎用于旧房间,1 用于新房间。如果我一遍又一遍地重复这个步骤,我每次离开并开始一个新房间时都会收到额外的事件。

我的组件如下所示:

class LobbyScreen extends Component {

  componentDidMount() {
    const {
      route: {
        params: {
          roomId
        }
      },
      socket,
      user
    } = this.props

    socket.on('updateRoom', () => {
      getRoom({ roomId })
    })

    socket.emit('joinRoom', {
      roomId, 
      userId: user._id
    })
  }

  render() {

    return (
      <View style={styles.container}>
        ...
      </View>
    )
  }  
}

我有一个简单的套接字服务器,用于处理连接以及接收和发出加入房间的事件:

io.on("connection", socket => {

  socket.on("joinRoom", ({ roomId, userId }) => {

    socket.join(roomId, () => {
      io.to(roomId).emit("updateRoom", { userId }) // tells everyone in the room that user with userId joined
    })

  })

})

【问题讨论】:

  • 我不知道反应,但我可以猜到每次安装组件时,套接字都会订阅updateRoom 事件。您应该对套接字使用单例模式,订阅房间不应该在组件安装逻辑中。如果它必须在组件安装逻辑中,那么你应该检查套接字是否已经订阅了那个房间io.adapter.allRooms(function (err, rooms) {...});
  • @Moazzam roomId 来自路由参数,因此每次访问该屏幕时它都是不同的值。
  • 重点是,您的组件每次都订阅新房间,但在销毁时不会调用room.leave()。基本上它订阅了多个房间。
  • 客户没有离开房间是正确的。但是服务器应该只将事件发送到用户加入io.to(roomId).emit的一个房间。
  • 好吧,如果你在服务器上使用io.sockets.in(roomId).emit('updateRoom', {userId}); 会怎样

标签: javascript node.js reactjs react-native sockets


【解决方案1】:

您可以在用户离开视图时使用componentWillUnmount 取消订阅套接字事件。这是一个反应生命周期方法,在组件离开之前调用。

根据套接字框架,您可以调用 close 方法来关闭连接,或者在您的情况下,您可能会找到一个取消订阅房间的方法。

componentWillUnmount() {
  socket.close()
}

Obvs 这太简单了,但你应该明白了。

【讨论】:

    【解决方案2】:

    问题在于你的服务器代码没有反应! 如果用户应该一次只出现在一个房间中,您应该将代码更改为:

    socket.on("joinRoom", ({ roomId, userId }) => {
        socket.leave(PREVIOUS_ROOM); // leave previous room before joining a new one
        socket.join(roomId, () => {
        io.to(roomId).emit("updateRoom", { userId })
    })
    

    【讨论】:

      猜你喜欢
      • 2016-12-14
      • 1970-01-01
      • 2015-01-05
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 1970-01-01
      • 2019-06-01
      • 2021-06-11
      相关资源
      最近更新 更多