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")
希望这有帮助!