我建立了一个HTML5多人游戏,该游戏依赖于服务器和客户端之间的时间同步是否合理。在大多数情况下,我使用的算法非常准确-它所做的只是估算客户端-服务器时间增量,即服务器上的当前时间与客户端上的当前时间之间的差。例如,如果服务器时间恰好比客户端时间早5秒,则时间增量为5000毫秒。

客户端和服务器(node.js)都用Javascript编写。该算法的工作原理如下:

  • 在客户端上记录时间:var clientTime = Date.now();
  • 对服务器执行Ping操作。当服务器收到消息时,它立即发送仅包含一件事的响应:服务器上收到消息的时间。
    var serverTime = Date.now();
    // Send serverTime to the client
    
  • 当客户端收到服务器响应时,立即记录时间:var clientTime2 = Date.now();

  • 现在,我们知道服务器收到消息时,客户端时间必须介于clientTimeclientTime2之间。

    如果服务器在客户端时间为clientTime时收到消息(即客户端->服务器请求以某种方式花费了0毫秒),则时间增量为var delta1 = (serverTime - clientTime);
    如果服务器在客户端时间为clientTime时收到消息(即服务器->客户端响应花费了0ms),则时间增量为var delta2 = (serverTime - clientTime2)

    因此,我们可以肯定地说时间增量在delta1delta2之间。现在,重复此过程很多次,每次根据您得到的结果缩小范围,就可以很好地估计时间增量。

    我已经在7种不同的浏览器和多台计算机上对此进行了数百次测试,但从未遇到过任何问题。从来没有不一致。

    但是,问题在于,我的服务器日志显示,不时地会有几个人疯狂地获得不一致的时间同步结果。这是一个玩家时间同步的实际示例:

    客户端经历了上述算法的 74个周期,并成功地将可能的时间增量范围缩小到[-186460,-186431],没有任何不一致的情况。 29毫秒精度

    在第75个周期(可能在第74个周期之后的几秒钟),客户端计算出可能的时间增量范围为:[-601,-596]。 5ms精度,除了它与过去的74个周期极其不一致:距 3分钟!

    我会把这种情况归咎于疯狂的案件,除非它每天发生近100次...这怎么会发生?使用Date.now()时是否有任何可能的错误?

    最佳答案

    performance.now()而不是Date.now(),因为performance.now()单调增加,并且不受时钟漂移的影响。查看评论,感谢大家的帮助!

    10-06 12:13