将JavaScript时钟与服务器时钟同步

4

背景

我正在创建一个AJAX聊天系统。它看起来像这样:

Mike - 嗨 Jane - 5分钟前

Jane - 嗨 Mike - 4分钟前

Mike - 最近怎么样?- 3秒钟前

Jane - 我很好 - 1秒钟前

Javascript每分钟轮询服务器,并且服务器会响应最新的10条消息。每个消息都附带有一个Unix时间戳(PHP time())。Javascript负责将用户当前缓冲的消息与此新的服务器响应合并。消息的交错和“X时间前”消息的准确性取决于Javascript时钟与服务器时钟同步的程度。


问题

如何准确地将Javascript时钟与服务器时钟同步?以下是我目前的代码。我想使它更加精确。目前它不考虑进行同步的Ajax往返时间。如何知道往返时间中发送、处理和接收的比例?另外,如何处理那些时钟水晶出了问题的用户 - 例如:现在是格林威治标准时间下午7:20,但他们的时钟实际上显示的是格林威治标准时间下午7:15?

Clock = {
   serverOffset = 0;

   synch: function() {
      new Ajax.Request(
         '/getServerTime.php', {
            onSuccess: function(transport) {
               this.serverOffset = parseInt(transport.responseText) - 
                  new Date().getTime() / 1000;
            }
         }
      );
   },

   getServerTime: function(myTime) {
      if (typeof(myTime) === 'undefined') {
         myTime = new Date().getTime() / 1000;
      }
      return myTime + this.serverOffset;
   },

   serverToMyTime: function(serverTime) {
      return serverTime - this.serverOffset;
   }
}
3个回答

3

我们曾经遇到过类似的问题。我们的解决方案是简单地忽略浏览器时钟。如果消息带有服务器时间戳,请按照该时间戳对其进行排序。然后,当呈现数据时,只需将其转换为浏览器时间即可。所有计算和排序都基于服务器时间。这样,你只需要保持服务器时间同步即可。


2
请注意,这需要服务器将您自己的消息回显给您——我猜测OP目前并没有这样做,但这是我绝对推荐的方法。让服务器将消息回显到发送它们的客户端意味着每个人都拥有相同的对话视图!包括两个人实际上在同一时间按下回车键的情况。服务器先接收到的消息将在两个客户端中首先出现。 - cdhowie
服务器和数据库 => UTC - Jad Joubran

3

正如我在这个答案中所解释的那样,你能够达到的精度是有限的。简而言之,任何小于请求往返时间的时钟偏差都是无法检测到的。如果你真的需要尽可能精确的时间,请创建一个专门用于获取时间的服务器请求类型,并尽一切可能使往返时间最快。

但你可以识别出本地时钟明显不准的浏览器,因为观察到的服务器时间不会落在请求的本地开始和结束时间之间。由于你不能再进一步缩小时间范围,所以只需在本地请求[start, end]区间内选择任意时间并将其视为接收到的服务器时间即可。


1

使用Flash和Socket服务器。如果您需要100%的准确性。我编写了一个套接字服务器,用于向Flash元素广播时间,并告诉它要显示什么。

这是一个金融应用程序,需要始终保持100%的准确性。

我们还将其与FMS配对,以便能够穿越企业防火墙。

如果您使用JavaScript,则无法实现准确性。

可能很快就会通过HTML5解决此问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接