我建立了一个HTML5多人游戏,该游戏依赖于服务器和客户端之间的时间同步是否合理。在大多数情况下,我使用的算法非常准确-它所做的只是估算客户端-服务器时间增量,即服务器上的当前时间与客户端上的当前时间之间的差。例如,如果服务器时间恰好比客户端时间早5秒,则时间增量为5000毫秒。
客户端和服务器(node.js)都用Javascript编写。该算法的工作原理如下:
var clientTime = Date.now();
var serverTime = Date.now();
// Send serverTime to the client
var clientTime2 = Date.now();
现在,我们知道服务器收到消息时,客户端时间必须介于
clientTime
和clientTime2
之间。如果服务器在客户端时间为
clientTime
时收到消息(即客户端->服务器请求以某种方式花费了0毫秒),则时间增量为var delta1 = (serverTime - clientTime);
如果服务器在客户端时间为
clientTime
时收到消息(即服务器->客户端响应花费了0ms),则时间增量为var delta2 = (serverTime - clientTime2)
。因此,我们可以肯定地说时间增量在
delta1
和delta2
之间。现在,重复此过程很多次,每次根据您得到的结果缩小范围,就可以很好地估计时间增量。我已经在7种不同的浏览器和多台计算机上对此进行了数百次测试,但从未遇到过任何问题。从来没有不一致。
但是,问题在于,我的服务器日志显示,不时地会有几个人疯狂地获得,不一致的时间同步结果。这是一个玩家时间同步的实际示例:
客户端经历了上述算法的 74个周期,并成功地将可能的时间增量范围缩小到[-186460,-186431],没有任何不一致的情况。 29毫秒精度。
在第75个周期(可能在第74个周期之后的几秒钟),客户端计算出可能的时间增量范围为:[-601,-596]。 5ms精度,除了它与过去的74个周期极其不一致:距 3分钟!
我会把这种情况归咎于疯狂的案件,除非它每天发生近100次...这怎么会发生?使用
Date.now()
时是否有任何可能的错误? 最佳答案
performance.now()
而不是Date.now()
,因为performance.now()
单调增加,并且不受时钟漂移的影响。查看评论,感谢大家的帮助!