【问题标题】:Logical issue regarding broadcasting messages to clients关于向客户端广播消息的逻辑问题
【发布时间】:2018-04-12 14:23:47
【问题描述】:

我目前正在使用套接字在 Node js 上开发游戏。

如果您可以想象一个多人游戏并拥有 3 个单独的房间。所以我去网站上,房间 1 有 16/16 名玩家,所以我去房间 2。这样的交易。

从逻辑上讲,在房间 1 中运行的游戏的游戏信息应该只发送给房间 1 中的用户,所以是这样的。

for (var i = 0; i < this.rooms.length; i++){
     for (var j = 0; j < this.rooms[i].players; j++){
         io.sockets.connected[this.rooms[i].players[j].socketid].emit('updateGame', this.rooms[i]);
     }
}

我没有测试过它或其他任何东西,但这将是它背后的一般逻辑。

它看起来很重服务器,因为它是一款快速移动的游戏,在更大的规模上,每人可能有 500 名玩家,每人以 60fps 的速度运行。

或者我可以将所有游戏的信息发送给每个人

this.socket.of('game').emit('updateGame', this.rooms);

并显示正确的一个客户端。

考虑到服务器压力、效率、最佳实践等,从逻辑上讲,最佳做法是什么。这似乎是第二个,但是当他们只玩 1 个错误时,将每个游戏/房间发送给客户端的想法让我有点恼火。

【问题讨论】:

    标签: node.js sockets socket.io


    【解决方案1】:

    关于处理加入现有房间或创建新房间我认为您可以在服务器端使用这样的 Redis Adapter:

    const io = require('socket.io')(3000);
    const redisAdapter = require('socket.io-redis');
    io.adapter(redisAdapter({ host: 'localhost', port: 6379 }));
    
    io.on('connection', function(client) {
        //Get allRooms by Redis Adapter
        io.of('/').adapter.allRooms((err, rooms) => {
            let statusJoinedRoom = false
            for (let room of rooms) {
                if (socket.id !== room) {
                    let numClients = io.sockets.clients(room).length
                    if (numClients <= MAX_CLIENTS_IN_ROOM) {
                        socket.join(room, () => {
                            console.log(`Joined room: ${room}`)
                            statusJoinedRoom = true
                            break
                        }
                    }
                }
            }
            if (!statusJoinedRoom) {
                socket.join(`room${rooms.length+1}`, (){
                    console.log('Created new room')
                })
            }
        })
    })
    

    工作流程是:Get all rooms -> Check count clients in each Room -> Join if count clients &lt; MAX_CLIENTS_IN_ROOM -> Create new room if all Rooms full

    关于性能 Redis 缓存将有助于存储房间、客户端数据。在正常情况下,这些数据将保存在 Node 线程的内存中。

    关于emit给同一个房间的所有客户,你可以用这个

    socket.to(socket.rooms).emit('hello', "to all clients in room except sender")
    

    希望对您有所帮助!

    【讨论】:

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