具有事件定时器的nod​​e.js可伸缩性(setTimeout)

我正在用node.js和socket.io构build一个基于回合的文本游戏。 每一回合都有一个超时时间,然后玩家失去回合并传递给下一个玩家。 我正在使用setTimeout函数,就像我在另一个问题中所说的那样。

问题是,我不知道如何扩展多个实例,也许多个服务器。 AIUI,如果我设置超时,我只能在同一个实例中清除它。 例如,如果一个玩家失去了轮回,例如,超时将被其他玩家轮stream更新,但是这个新玩家将不能访问该定时器对象来清除它,因为它正在第一个玩家的实例上运行。

我看了Redis的pub / subfunction(我将不得不使用它),但是我没有发现任何有关定时事件或延迟发布的内容。

TL; DR,如何保持一个实例/服务器独立的定时器?

我find的解决scheme是使用一些消息系统(Redis pub / sub在我的情况)来保持每个播放器实例了解当前状态。

每个玩家都有一个自己处理自己的工人实例(这包括计时器)。 当它结束时,无论是通过玩家移动还是通过超时,它都前进转弯计数器,并通过酒吧/子通知所有实例新的转弯号码。 所有的实例收到消息,并将转数与自己的玩家号码进行比较。 如果匹配,那么该实例将处理该转,并重复该循环。

我会尝试提供一个例子(更多的伪代码):

 // pub & sub are Redis publisher & subscriber clients, respectively function Game (totalPlayers, playerNumber) { this.turn = 0 this.totalPlayers = totalPlayers this.playerNumber = playerNumber // Subscribe to Redis events sub.on('message', function (channel, message) { message = JSON.parse(message) switch(message.type) { case 'turn': this.onTurn(message.turn) } }) sub.subscribe(this.channel, function() { this.checkStart() }) } Game.prototype.checkStart = function () { // This checks if this instance is for // the last player and, if so, starts the // main loop: if(this.playerNumber == this.totalPlayers - 1) { pub.publish(this.channel, JSON.stringify({type: 'turn', turn: 0}) } } Game.prototype.onTurn = function(turn) { this.turn = turn if(this.turn == this.playerNumber) { this.timer = setTimeout(this.endTurn.bind(this), this.turnTime) } } Game.prototype.endTurn = function() { this.turn = (this.turn + 1) % this.totalPlayers pub.publish(this.channel, JSON.stringify({type: 'turn', turn: this.turn}) } 

这种方法我遇到了一些问题,主要的问题是初始状态,如果几乎同时连接的玩家不太对。 发送信息并确保所有实例同步也是一个好主意。

如果有人遇到同样的问题,我希望我明确expression过。