3

我正在创建一个可以有许多游戏房间的多人游戏,并且我想为每个房间关联一个游戏对象(或游戏状态);我正在使用 NodeJS、Socket.io、socket.io-redis(不确定是否需要这个)。

为了更清楚,我也在使用 Typescript。

我尝试使用 socket.io-redis 的remoteJoin()功能并通过使用成功将游戏对象设置到房间

io.of('/').adapter.rooms[<roomId>].game = Game.

但是,我读到这不是设置房间宽对象的正确方法。

创建房间的事件

socket.on('create-game', (createData: any) => {
    this.io.of('/').adapter.remoteJoin(socket.id, createData.roomId, (err: any) => {
        let player = new Player(createData.username)
        let game = new Game(createData.roomId)

        game.addPlayer(player)

        this.io.of('/').adapter.rooms[createData.roomId].game = game
    })
})

加入房间的事件

socket.on('join-game', (joinData: any) => {
    this.io.of('/').adapter.remoteJoin(socket.id, joinData.roomId, (err: any) => {
        let player = new Player(joinData.username)
        let game = this.io.of('/').adapter.rooms[joinData.roomId].game as Game

        game.addPlayer(player)
    })
})

事件发生了什么create-game

  1. 传入的数据用于创建一个Player
  2. 和一个Game物体
  3. 然后player添加到game对象
  4. 最后,game对象被添加到房间

事件发生了什么join-game

  1. 传入的数据用于创建一个Player
  2. Game对象是通过从房间中检索它来创建的
  3. player被添加到游戏对象

经过无数天/周?搜索时,我偶然发现了这个 Stackoverflow 线程:socket.io, how to attach state to a socket room

这个答案的意思是基本上不做我上面做的事情。他们的建议是创建自己的数据结构(甚至不知道如何开始这样做)。

我发现的其他答案说只是在服务器中创建一个全局变量,但同样,其他人说这是不好的做法(我也这么认为)。

另一个流行的答案是将游戏存储在 Redis 中,但 Redis 不能保存复杂的 Javascript 对象。我现在 Redis 可以通过hmset()函数保存哈希数据,但我发现这不适用于像Game对象这样复杂的东西,包括函数、构造函数和 getter/setter。

另一个突出的答案是仅在“回合”后将游戏存储到数据库中,但在我的情况下,一旦游戏结束,房间就会关闭并且相关的游戏会被销毁;我不需要在“保存游戏”的意义上坚持这个游戏。

4

0 回答 0