Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to synchronise a client webpage timer with the server

What is the best way to synchronise the time on a webpage with the server?

My webpage needs to start a countdown at the same time for all users, and and end at exactly the same time to prevent any one user having a slight time advantage.

My problem is similar to this question but the accepted answer helps but does not fully answer my concerns: how-to-sync-a-javascript-countdown-with-server-time

I use Ajax after pageload to get the server time, but am I guaranteed over 15 minutes that the countdown will end at exactly the same time for each client?

Even if the timers accurately measure the time, there could still be a discrepancy of just under 1 second between client pages caused by disregarding the milliseconds for the setInterval - is there any way to overcome this?

like image 867
FluffyKitten Avatar asked Feb 19 '12 16:02

FluffyKitten


2 Answers

The accepted answer is good and helped inspire me as I wrote a library to solve this problem. The library yields more precise answers by looking at the load times of itself, rather than the whole page (as done with performance.timing above) and then gets even better precision by following with a series of 10 XMLHttpRequests. Also, addressing your second concern, my library doesn't disregard the milliseconds (as does the accepted answer).

The library is called ServerDate and is freely available.

Here's part of the README:

You can use ServerDate as you would use the Date function or one of its instances, e.g.:

> ServerDate()
"Mon Aug 13 2012 20:26:34 GMT-0300 (ART)"

> ServerDate.now()
1344900478753

> ServerDate.getMilliseconds()
22

There is also a new method to get the precision of ServerDate's estimate of the server's clock (in milliseconds):

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

You can see the difference between the server's clock and the browsers clock, in milliseconds:

> ServerDate - new Date()
39
like image 128
David Braun Avatar answered Sep 21 '22 04:09

David Braun


In modern browsers, you can achieve this by assigning a timestamp to a JavaScript variable, and use the Performance object to calculate the exact time.

Example:

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.
};

For more information on this object, have a look at the MDN's article.
A demo is provided here.

like image 24
Rob W Avatar answered Sep 21 '22 04:09

Rob W