【问题标题】:Socket.io connection joining the wrong roomSocket.io 连接加入了错误的房间
【发布时间】:2017-06-03 01:49:51
【问题描述】:

当向localhost:3000/:id 发出请求时,我想创建一个房间并将客户端添加到其中。然后我希望该客户采取的行动仅广播给该房间中的其他客户。这是处理该问题的服务器端代码:

app.get('/:id', function response(req, res) {
    io.on('connection', function (socket) {

            socket.join('/game-' + req.params.id);

            socket.on('action', function (action) {
                switch (action.type) {
                    case 'TOGGLE_ACTIVE_PLAYER':
                        return socket.broadcast.to('/game-' + req.params.id).emit('action', toggleActivePlayer())
                    case 'SET_SLOT_PREVIEW':
                        return socket.broadcast.to('/game-' + req.params.id).emit('action', setSlotPreview(action.colIndex))
                    case 'CLEAR_SLOT_PREVIEW':
                        return socket.broadcast.to('/game-' + req.params.id).emit('action', clearSlotPreview(action.colIndex))
                    case 'PLAYER_MOVED':
                        return socket.broadcast.to('/game-' + req.params.id).emit('action', playerMoved(action.colIndex))
                    case 'CHECK_FOR_WINNER':
                        return socket.broadcast.to('/game-' + req.params.id).emit('action', checkForWinner())
                    case 'CLEAR_BOARD':
                        return socket.broadcast.to('/game-' + req.params.id).emit('action', clearBoard())
                    case 'CLEAR_WINNER':
                        return socket.broadcast.to('/game-' + req.params.id).emit('action', clearWinner())
                    case 'RESET_GAME':
                        return socket.broadcast.to('/game-' + req.params.id).emit('action', resetGame())
                }
            })
    });
    res.end();
});

我遇到的问题是,当使用新的 id 参数 (localhost:300/newIdParam) 建立连接时,会创建一个名为 newIdParam 的房间并将该客户端添加到其中,但该客户端也被不恰当地添加到现有房间。我可以通过检查io.sockets.adapter.rooms 对象来判断客户在两个房间中:

  '/game-123': 
   Room {
     sockets: 
      { '/#KIq0i-_oaf_mtM8AAAAK': true,
        '/#Sokr_2ROg0culZ6bAAAL': true,
        '/#w6XRgbfF3Q2TIicXAAAM': true },
     length: 3 },
  '/#Sokr_2ROg0culZ6bAAAL': Room { sockets: { '/#Sokr_2ROg0culZ6bAAAL': true }, length: 1 },
  '/#w6XRgbfF3Q2TIicXAAAM': Room { sockets: { '/#w6XRgbfF3Q2TIicXAAAM': true }, length: 1 },
  '/game-456': Room { sockets: { '/#w6XRgbfF3Q2TIicXAAAM': true }, length: 1 } }

通知套接字 id #w6XRgbfF3Q2TIicXAAAM 存在于两个房间中。同样,这些房间是通过将 id 作为路由参数发出请求来创建的,如下所示:

localhost:3000/123

该请求将创建一个名为 game-123 的房间,并自动添加请求的客户端。

提前感谢您的任何想法。

【问题讨论】:

  • 作为旁注,您为什么不只是发出 action.type 作为事件名称?这会破坏你的逻辑,你不需要一个 switch-case 块。
  • 客户端应用程序正在向服务器发送 redux 操作,所以这只是一个服务器端 reducer,redux reducer 对用户 switch 语句很常见。这是我决定使用 switch 语句的唯一原因。
  • 好吧,这很有道理。就个人而言,我一直发现 redux 的编写方式有点像 JavaScript 反模式,但我想这越来越受到人们的关注。

标签: javascript node.js express websocket socket.io


【解决方案1】:

在这里,如果您需要类似用户连接到新房间,则用户不应在旧房间,因此只有一个用户连接的房间,然后您必须强制用户在断开连接时离开房间,如下所示,

socket.on('disconnect', function(){
    socket.leave("roomname");
});

【讨论】:

    猜你喜欢
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 2020-02-05
    • 2018-04-06
    • 1970-01-01
    • 2016-12-14
    相关资源
    最近更新 更多