如何将客户端网页计时器与服务器同步



将网页上的时间与服务器同步的最佳方式是什么?

我的网页需要为所有用户同时开始倒计时,并在完全相同的时间结束,以防止任何一个用户有轻微的时间优势。

我的问题与这个问题类似,但公认的答案有帮助,但并不能完全回答我的担忧:如何同步a-javascript-countdown with-server-time

我在页面加载后使用Ajax来获取服务器时间,但我能保证在15分钟内每个客户端的倒计时都会在同一时间结束吗?

即使计时器准确地测量了时间,由于忽略setInterval的毫秒数,客户端页面之间仍可能存在不到1秒的差异——有什么方法可以克服这一点吗?

被接受的答案很好,在我编写一个库来解决这个问题时给了我灵感。该库通过查看自身的加载时间而不是整个页面(如上面的performance.timing所做的那样)来获得更精确的答案,然后通过下面的10个XMLHttpRequest来获得更好的精度。此外,为了解决您的第二个问题,我的库不会忽略毫秒(接受的答案也是如此)。

该库名为ServerDate,可免费使用。

以下是自述文件的一部分:

您可以像使用Date函数或其一个函数一样使用ServerDate实例,例如:

> ServerDate()
"Mon Aug 13 2012 20:26:34 GMT-0300 (ART)"
> ServerDate.now()
1344900478753
> ServerDate.getMilliseconds()
22

还有一种新的方法可以获得ServerDate对服务器的时钟(以毫秒为单位):

> ServerDate.toLocaleString() + " ± " + ServerDate.getPrecision() + " ms"
"Tue Aug 14 01:01:49 2012 ± 108 ms"

您可以看到服务器时钟和浏览器时钟之间的差异,以毫秒为单位:

> ServerDate - new Date()
39

在现代浏览器中,您可以通过为JavaScript变量分配时间戳来实现这一点,并使用Performance对象来计算确切的时间。

示例:

var tsp = new Date('Sun Feb 19 2012 17:55:14 GMT+0100 (CET)'); // "Timestamp"
window.onload = function() {
    var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {};
    tsp.setTime(tsp.getTime() + performance.timing.loadEventStart - performance.timing.navigationStart
    // after window.onload, you're sync with the server
    // Example of timer:
    setInterval(function() {
        tsp.setSeconds(tsp.getSeconds() + 1);
        document.title = tsp.toString();
    }, 1000); // 1000 ms = timer may be off by 500ms.
};

有关此对象的更多信息,请参阅MDN的文章
这里提供了一个演示。

理想情况下,您的解决方案将包括服务器发出提交表单同时对所有客户端开放的信号。为此,如果你不介意将使用旧浏览器的人排除在外,你可以使用网络套接字。对这些浏览器使用长轮询也会出现故障。

不过,我不确定websocket与PHP的结合效果如何。

我只使用过socket.io和nodeJS。使用该解决方案,设置服务器端超时并在超时完成时同时通知所有客户端将是微不足道的。它会自动检测浏览器支持,并选择最适合给定浏览器的方法。

使用此解决方案,客户端只有在服务器告知其已准备就绪时才允许提交。只要您提交的服务器执行验证,您就可以了。

最新更新