Synchronizing Javascript clock with server clock
BACKGROUND
I'm creating an AJAX chat system. It looks something like this:
Mike - hi Jane - 5 minutes ago
Jane - hi Mike - 4 minutes ago
Mike - how's it going - 3 seconds ago
Jane - I'm doing good - 1 second ago
Javascript polls the server every minute and the server responds with 10 of the newest messages. Attached to each message is a Unix timestamp (PHP time()). Javascript is responsible for merging the buffered messages the user currently has with this new server response. The interleaving of messages and accuracy of the "X time ago" message is dependent on how well the Javascript clock is synched with the server clock.
QUESTION
How do you accurately synch the Javascript clock with server clock? Below is what I have so far. I would like to make it more accurate. Currently it does not consider the roundtrip time of the Ajax which does the synching. How do I know the proportion of the roundtrip that is sending, processing, and receiving? Also, how do you deal with users who's clock crystals are just plain busted - for example: it's 7:20 pm GMT but their clock actually says 7:15 pm GMT?
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;
}
}
There's a limit to how precise you can be, as I explained in this answer -- in essence, any clock skew smaller than the request round-trip time is undetectable. If you really need the time to be as precise as possible, create a special request type to the server that just gets the time, and do whatever you can to make the round-trip as fast as possible.
You can identify browsers whose local clocks are clearly insane, though, because the observed server time will not fall between the request's local start and end time. Since you can't tighten it down much farther than that, just pick an arbitrary time within the local request [start, end] interval and treat that as being equivalent to the received server time.
We've had a similar problem. Our solution was to simply ignore the browser clock. If the messages come in with a server timestamp, just sort them by that timestamp. Then all you need to do is when presenting the data, just convert that to browser time. All calculations and sorting were based off of server time though. This way, all you have to do is keep your servers times all synced.
Use flash and a socket server. If you need to be 100% accurate. I have written a socket server for an application that broadcasts the time to a flash element every 1 second and tells it exactly what to display.
This is a financial based app where it needs to always be 100% accurate.
We also paired it up with FMS to be able to tunnel through corporate firewalls.
If you use javascript you won't be able to achieve accuracy.
possibly html5 will solve this issue with sockets soon
链接地址: http://www.djcxy.com/p/86166.html上一篇: 循环定时器/时钟以毫秒为单位