有关向客户端广播消息的逻辑问题



im 目前正在使用 sockets 在 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 个错误时,将每个游戏/房间发送给客户端的想法让我感到不安。

关于句柄加入存在房间或创建新房间 我认为您可以在服务器端像这样使用 Redis 适配器:

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 < 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")

希望这有帮助!

相关内容

最新更新