【问题标题】:NodeJs & Socket.IO turn based multiplayer game, question about pairing playersNodeJs & Socket.IO 回合制多人游戏,关于配对玩家的问题
【发布时间】:2019-05-21 02:27:36
【问题描述】:

我正在开发一款多人回合制游戏(例如国际象棋),应该支持很多玩家(这就是想法)。我的问题是关于我正在开发的一项服务,它是配对系统,负责配对 2 名玩家以开始一个房间并开始游戏。

所以,这就是配对服务:

matchPlayers() {
        if (this.players.length >= 2) {
            let player1 = this.players.shift();
            let player2 = this.players.shift();

            if (player1 !== undefined && player2 !== undefined) {
                player1.getSocket().emit('opponent_found');
                player2.getSocket().emit('opponent_found');
                return this.createMatchInDataBaseApiRequest(player1, player2)
                    .then(function (data) {
                        let room = new RoomClass(data.room_id, player1, player2);

                        player1.setRoom(room);
                        player2.setRoom(room);

                        return room;
                });
            }
        }

        return false;
    }

在服务器的入口点,我将每个新的套接字连接推送到一个数组“PlayersPool”,该数组供等待匹配的玩家使用。

现在我的方法是在有可用用户时配对用户,(FIFO - 先进先出)。

我看到的这个配对系统的问题(和疑问)是:

  • 这取决于新用户,每次新用户连接时都会执行,流程是:一个用户连接,get's添加到池中,并检查是否有用户等待配对,如果有创建了一个房间,他们可以玩,如果没有,他会被添加到等待池中;直到新用户连接并执行代码等等...

  • 如果在某些奇怪的情况下(不确定是否会发生)2 名玩家同时被添加到等待池中,会发生什么情况,此服务会发现池为空并且不会创建房间:为了解决这个问题,也许有另一个服务总是在运行并检查池?最好的方法是什么?这甚至会发生吗?在哪种情况下?

感谢您的帮助。

【问题讨论】:

  • 好吧,您还没有提供处理传入连接、将它们添加到播放器池或从哪里调用 matchPlayers() 等的代码。但通常,不,它应该不可能一次将多个人添加到池中。即使两个玩家同时连接,代码也不是多线程的,所以总是先处理一个玩家。 (尽管哪个先出现可能是任意的。)

标签: node.js socket.io


【解决方案1】:

我猜这个特定的代码 sn-p 在服务器上?如果是这样,假设只有一个服务器,那么就没有“竞争条件”:node.js 是单线程的,正如 IceMetalPunk 提到的,所以如果你每次向this.players 添加播放器时都运行这个函数,你应该没事。

还有其他原因需要定期检查玩家池:您添加到池中的玩家可能已断开连接(由于超时或关闭浏览器),因此您应该删除他们;您可能还想处理玩家已经等待很长时间的情况 - X 秒后,您是否应该更新玩家的进度,计算他们的估计等待时间,也许生成一个 AI 玩家让他们在等待时与之交互等。

【讨论】:

    【解决方案2】:

    您可能会遇到“竞争条件”,它在此包中进行了说明,它为您提供了锁定机制。 https://www.npmjs.com/package/async-lock

    只有当你在单个进程中运行 node.js 时,该包才会有用,这意味着你没有多个服务器,或者节点集群运行多个进程。

    在这种情况下,您将不得不实现分布式锁定机制,这是分布式计算中最复杂的事情之一,但是今天您可以使用 npm 包进行 Redlock 算法,设置 3 个 redis 服务器并开始使用。 没有玩家的游戏开销太大。

    Node.js 不是单线程的,这里是其中一位创建者的解释。

    上午主题演讲 - 您需要了解的有关 Node.js 事件循环的一切 - Bert Belder,IBM
    https://www.youtube.com/watch?v=PNa9OMajw9w

    结论,保持简单,在单节点进程中运行并使用“async-lock”包。

    如果您的服务器发展成为 MMO,您将需要阅读分布式计算: 如何进行分布式锁定: https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html

    关于数据密集型应用的书籍 http://dataintensive.net/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多