All Downloads are FREE. Search and download functionalities are using the official Maven repository.

js.dojox.cometd.timesync.js Maven / Gradle / Ivy

Go to download

A Mule transport for receiving and dispatching AJAX events using Cometd (Bayeux)

There is a newer version: 3.9.0
Show newest version
if(!dojo._hasResource["dojox.cometd.timesync"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojox.cometd.timesync"] = true;
dojo.provide("dojox.cometd.timesync");
dojo.require("dojox.cometd");

/**
 * this file provides the time synchronization extension to cometd.
 * Timesync 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.
 *
 * With each handshake or connect, the extension sends timestamps within the 
 * ext field like: {ext:{timesync:{tc:12345567890},...},...}
 * where ts is the timestamp in ms since 1970 of when the message was sent.
 *
 * A cometd server that supports timesync, should respond with and ext field
 * like: {ext:{timesync:{tc:12345567890,ts:1234567900,p:123},...},...}
 * where ts is the timestamp sent by the client, te is the timestamp on the server
 * of when the message was received and p is the poll duration in ms - ie the
 * time the server took before sending the response.
 *
 * 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. The assumption is made that the network is
 * symmetric for traversal time, so the offset between the two clocks is 
 * ts-tc-(now-tc-p)/2. In practise networks (and the cometd client/server software)
 * is never perfectly symmetric, so accuracy is limited by the difference, which 
 * can be 10s of milliseconds.
 *
 * 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 with the dojox.cometd.timesync._window element.
 */
dojox.cometd.timesync= new function(){

    this._window=10;// The window size for the sliding average of offset samples.
    this._minWindow=4;// The window size for the sliding average of offset samples.
    this._offsets=new Array(); // The samples used to calculate the average offset.
    this.offset=0;    // The offset in ms between the clients clock and the servers clock. Add this to the local
            // time epoch to obtain server time.
    this.samples=0; // The number of samples used to calculate the offset. If 0, the offset is not valid.

    this.getServerTime=function(){ // return: long
        // Summary:
        //    Calculate the current time on the server
        //
        return new Date().getTime()+this.offset;
    }

    this.getServerDate=function(){ // return: Date
        // Summary:
        //    Calculate the current time on the server
        //
        return new Date(this.getServerTime());
    }

    this.setTimeout=function(/*function*/call,/*long|Date*/atTimeOrDate){
        // Summary:
        //    Set a timeout function relative to server time
        // call:
        //    the function to call when the timeout occurs
        // atTimeOrTime:
        //    a long timestamp or a Date representing the server time at
        //    which the timeout should occur.

        var ts=(atTimeOrDate instanceof Date)?atTimeOrDate.getTime():(0+atTimeOrDate);
        var tc=ts-this.offset;
        var interval=tc-new Date().getTime();
        if (interval<=0)
            interval=1;
        return setTimeout(call,interval);
    }

    this._in=function(/*Object*/msg){
        // Summary:
        //    Handle incoming messages for the timesync extension.
        // description:
        //    Look for ext:{timesync:{}} field and calculate offset if present.
        // msg:
        //    The incoming bayeux message

        var channel=msg.channel;
        if (channel &&  channel.indexOf('/meta/')==0){
            if (msg.ext && msg.ext.timesync){
                var sync=msg.ext.timesync;
                var now=new Date().getTime();

                this._offsets.push(sync.ts-sync.tc-(now-sync.tc-sync.p)/2);
                if (this._offsets.length>this._window)
                    this._offsets.shift();
                this.samples++;
                var total=0;
                for (var i in this._offsets)
                    total+=this._offsets[i];
                this.offset=parseInt((total/this._offsets.length).toFixed());

                if (this.samples




© 2015 - 2024 Weber Informatics LLC | Privacy Policy