Skip navigation.

CometD Timesync Extension

CometD Timesync Extension

The timesync extension uses the messages exchanged between a client and a server to calculate the offset between the client's clock and the server's clock.
This is independent from the timestamp extension, which uses the local clock for all timestamps.
This extension requires both a client-side extension and a server-side extension. The server-side extension is available in Java.

Enabling the Server-side Extension

To enable support for acknowledged messages, the extension must be added to the org.cometd.Bayeux instance during initialization:

bayeux.addExtension(new org.cometd.server.ext.TimesyncExtension());

Enabling the Client-side Extension

The client side extension binding for Dojo is provided by dojox/cometd/timesync.js and it is sufficient to use Dojo's dojo.require mechanism:

dojo.require("dojox.cometd.timesync");

The client side extension binding for jQuery is provided by the file jquery.cometd-timesync.js. This file must be included in the HTML page via the <script> tag:

<script type="text/javascript" src="jquery.cometd-timesync.js"></script>

In both Dojo and jQuery extension bindings, the extension is registered on the default cometd object under the name "timesync".

Timesync Extension Details

The timesync extension allows the client and server to exchange time information on every handshake and connect message so that the client may calculate an approximate offset from it's own clock epoch to that of the server.
The algorithm used is very similar to the NTP algorithm.

With each handshake or connect, the extension sends timestamps within the ext field like:

{ext:{timesync:{tc:12345567890,l:23,o:4567},...},...}

where:

  • tc is the client timestamp in ms since 1970 of when the message was sent
  • l is the network lag that the client has calculated
  • o is the clock offset that the client has calculated

The accuracy of the offset and lag may be calculated with tc-now-l-o, which should be zero if the calculated offset and lag are perfectly accurate.

A Bayeux server that supports timesync, should respond only if the measured accuracy value is greater than accuracy target.
The response will be an ext field like:

{ext:{timesync:{tc:12345567890,ts:1234567900,p:123,a:3},...},...}

where:

  • tc is the client timestamp of when the message was sent
  • ts is the server timestamp of when the message was received
  • p is the poll duration in ms - ie the time the server took before sending the response
  • a is the measured accuracy of the calculated offset and lag sent by the client

On receipt of the response, the client is able to use current time to determine the total trip time, from which p is subtracted to determine an approximate two way network traversal time. Thus:

  • lag = (now-tc-p)/2
  • offset = ts-tc-lag

In order to smooth over any transient fluctuations, the extension keeps a sliding average of the offsets received.
By default this is over 10 messages, but this can be changed by passing a configuration object during the creation of the extension:

// Unregister the default timesync extension
cometd.unregisterExtension('timesync');

// Re-register with different configuration
cometd.registerExtension('timesync', new org.cometd.TimeSyncExtension({ maxSamples: 20 }));

The client-side timesync extension also exposes several methods to deal with the result of the time synchronization:

  • getNetworkLag(), to obtain the calculated network latency between client and server
  • getTimeOffset(), to obtain the offset between the client's clock and the server's clock in ms
  • getServerTime(), to obtain the server's time
  • setTimeout(), to schedule a function to be executed at a certain server time