4

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

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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.

2 Comments

Note that this requires that the server echo your own messages back to you -- I am guessing that the OP is not currently doing this, but this is the approach I would definitely recommend. Having the server echo messages back to the client that sent them means that everyone has the same view of the conversation! This includes cases where both people actually hit the enter key at the same instant in time. The message that the server receives first will appear first in both clients.
the server and the database => UTC
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.