diff options
Diffstat (limited to 'js/dojo-1.7.2/dojox/cometd')
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/HttpChannels.js | 37 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/README | 29 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/RestChannels-loadInit.js | 11 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/_base.js | 759 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/ack.js | 55 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/callbackPollTransport.js | 107 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/longPollTransport.js | 7 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/longPollTransportFormEncoded.js | 162 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/longPollTransportJsonEncoded.js | 164 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/timestamp.js | 13 | ||||
| -rw-r--r-- | js/dojo-1.7.2/dojox/cometd/timesync.js | 146 |
11 files changed, 1490 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/cometd/HttpChannels.js b/js/dojo-1.7.2/dojox/cometd/HttpChannels.js new file mode 100644 index 0000000..5b13397 --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/HttpChannels.js @@ -0,0 +1,37 @@ +//>>built +// wrapped by build app +define("dojox/cometd/HttpChannels", ["dijit","dojo","dojox","dojo/require!dojox/io/httpParse,dojox/cometd/RestChannels"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.HttpChannels"); + +dojo.require("dojox.io.httpParse"); +dojo.require("dojox.cometd.RestChannels"); +// Note that cometd _base is _not_ required, this can run standalone, but ifyou want +// cometd functionality, you must explicitly load/require it elsewhere, and cometd._base +// MUST be loaded prior to HttpChannels ifyou use it. + +// summary: +// HttpChannels - An HTTP Based approach to Comet transport with full HTTP messaging +// semantics including REST. HttpChannels is exactly the same as RestChannels, loading HttpChannels simply ensures that http parsing +// capabilities are present for application/http messages + +// description: +// This can be used: +// 1. As a cometd transport +// 2. As an enhancement for the REST RPC service, to enable "live" data (real-time updates directly alter the data in indexes) +// 2a. With the JsonRestStore (which is driven by the REST RPC service), so this dojo.data has real-time data. Updates can be heard through the dojo.data notification API. +// 3. As a standalone transport. To use it as a standalone transport looks like this: +// | dojox.cometd.HttpChannels.open(); +// | dojox.cometd.HttpChannels.get("/myResource",{callback:function(){ +// | // this is called when the resource is first retrieved and any time the +// | // resource is changed in the future. This provides a means for retrieving a +// | // resource and subscribing to it in a single request +// | }); +// | dojox.cometd.HttpChannels.subscribe("/anotherResource",{callback:function(){ +// | // this is called when the resource is changed in the future +// | }); +// Channels HTTP can be configured to a different delays: +// | dojox.cometd.HttpChannels.autoReconnectTime = 60000; // reconnect after one minute +// +dojox.cometd.HttpChannels = dojox.cometd.RestChannels; + +}); diff --git a/js/dojo-1.7.2/dojox/cometd/README b/js/dojo-1.7.2/dojox/cometd/README new file mode 100644 index 0000000..05a42a2 --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/README @@ -0,0 +1,29 @@ +------------------------------------------------------------------------------- +Cometd (client) +------------------------------------------------------------------------------- +Version 0.4 +Release date: May 29, 2007 +------------------------------------------------------------------------------- +Project state: beta +------------------------------------------------------------------------------- +Project authors + Alex Russell (alex@dojotoolkit.org) + Greg Wilkins +------------------------------------------------------------------------------- +Project description + +Low-latency data transfer from servers to clients. dojox.cometd implements a +Bayeux protocol client for use with most Bayeux servers. See cometd.com for +details on Cometd or on the Bayeux protocol. +------------------------------------------------------------------------------- +Dependencies: + +Needs a cooperating Bayeux server +------------------------------------------------------------------------------- +Documentation + +See http://cometd.com +------------------------------------------------------------------------------- +Installation instructions + +Use this library with (preferably through) an existing Cometd server. diff --git a/js/dojo-1.7.2/dojox/cometd/RestChannels-loadInit.js b/js/dojo-1.7.2/dojox/cometd/RestChannels-loadInit.js new file mode 100644 index 0000000..5b168bc --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/RestChannels-loadInit.js @@ -0,0 +1,11 @@ +//>>built +// generated by build app +define("dojox/cometd/RestChannels-loadInit", [], { + names:["dijit","dojo","dojox"], + def:function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.RestChannels"); +dojo.require("dojox.rpc.Client"); +dojo.require("dojo._base.url"); +dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener"); +} +}); diff --git a/js/dojo-1.7.2/dojox/cometd/_base.js b/js/dojo-1.7.2/dojox/cometd/_base.js new file mode 100644 index 0000000..d5a35e4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/_base.js @@ -0,0 +1,759 @@ +//>>built +// wrapped by build app +define("dojox/cometd/_base", ["dijit","dojo","dojox","dojo/require!dojo/AdapterRegistry"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd._base"); +dojo.require("dojo.AdapterRegistry"); + + +/* + * this file defines Comet protocol client. Actual message transport is + * deferred to one of several connection type implementations. The default is a + * long-polling implementation. A single global object named "dojox.cometd" is + * used to mediate for these connection types in order to provide a stable + * interface. + * + * extensions modules may be loaded (eg "dojox.cometd.timestamp", that use + * the cometd._extendInList and cometd._extendOutList fields to provide functions + * that extend and handling incoming and outgoing messages. + * + * By default the long-polling and callback-polling transports will be required. + * If specific or alternative transports are required, then they can be directly + * loaded. For example dojo.require('dojox.cometd.longPollTransportJsonEncoded') + * will load cometd with only the json encoded variant of the long polling transport. + */ + +dojox.cometd = { + Connection: function(prefix){ // This constructor is stored as dojox.cometd.Connection + // summary + // This constructor is used to create new cometd connections. Generally, you should use + // one cometd connection for each server you connect to. A default connection instance is + // created at dojox.cometd. + // To connect to a new server you can create an instance like: + // var cometd = new dojox.cometd.Connection("/otherServer"); + // cometd.init("http://otherServer.com/cometd"); + // + // prefix is the prefix for all the events that are published in the Dojo pub/sub system. + // You must include this prefix, and it should start with a slash like "/myprefix". + + // cometd states: + // unconnected, handshaking, connecting, connected, disconnected + dojo.mixin(this, { + prefix: prefix, + _status: "unconnected", + _handshook: false, + _initialized: false, + _polling: false, + + expectedNetworkDelay: 10000, // expected max network delay + connectTimeout: 0, // If set, used as ms to wait for a connect response and sent as the advised timeout + + version: "1.0", + minimumVersion: "0.9", + clientId: null, + messageId: 0, + batch: 0, + + _isXD: false, + handshakeReturn: null, + currentTransport: null, + url: null, + lastMessage: null, + _messageQ: [], + handleAs: "json", + _advice: {}, + _backoffInterval: 0, + _backoffIncrement: 1000, + _backoffMax: 60000, + _deferredSubscribes: {}, + _deferredUnsubscribes: {}, + _subscriptions: [], + _extendInList: [], // List of functions invoked before delivering messages + _extendOutList: [] // List of functions invoked before sending messages + + }); + + this.state = function() { + return this._status; + } + + this.init = function( /*String*/ root, + /*Object?*/ props, + /*Object?*/ bargs){ // return: dojo.Deferred + // summary: + // Initialize the cometd implementation of the Bayeux protocol + // description: + // Initialize the cometd implementation of the Bayeux protocol by + // sending a handshake message. The cometd state will be changed to CONNECTING + // until a handshake response is received and the first successful connect message + // has returned. + // The protocol state changes may be monitored + // by subscribing to the dojo topic "/prefix/meta" (typically "/cometd/meta") where + // events are published in the form + // {cometd:this,action:"handshake",successful:true,state:this.state()} + // root: + // The URL of the cometd server. If the root is absolute, the host + // is examined to determine if xd transport is needed. Otherwise the + // same domain is assumed. + // props: + // An optional object that is used as the basis of the handshake message + // bargs: + // An optional object of bind args mixed in with the send of the handshake + // example: + // | dojox.cometd.init("/cometd"); + // | dojox.cometd.init("http://xdHost/cometd",{ext:{user:"fred",pwd:"secret"}}); + + // FIXME: if the root isn't from the same host, we should automatically + // try to select an XD-capable transport + props = props || {}; + // go ask the short bus server what we can support + props.version = this.version; + props.minimumVersion = this.minimumVersion; + props.channel = "/meta/handshake"; + props.id = "" + this.messageId++; + + this.url = root || dojo.config["cometdRoot"]; + if(!this.url){ + throw "no cometd root"; + return null; + } + + // Are we x-domain? borrowed from dojo.uri.Uri in lieu of fixed host and port properties + var regexp = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"; + var parts = ("" + window.location).match(new RegExp(regexp)); + if(parts[4]){ + var tmp = parts[4].split(":"); + var thisHost = tmp[0]; + var thisPort = tmp[1]||"80"; // FIXME: match 443 + + parts = this.url.match(new RegExp(regexp)); + if(parts[4]){ + tmp = parts[4].split(":"); + var urlHost = tmp[0]; + var urlPort = tmp[1]||"80"; + this._isXD = ((urlHost != thisHost)||(urlPort != thisPort)); + } + } + + if(!this._isXD){ + props.supportedConnectionTypes = dojo.map(dojox.cometd.connectionTypes.pairs, "return item[0]"); + } + + props = this._extendOut(props); + + var bindArgs = { + url: this.url, + handleAs: this.handleAs, + content: { "message": dojo.toJson([props]) }, + load: dojo.hitch(this,function(msg){ + this._backon(); + this._finishInit(msg); + }), + error: dojo.hitch(this,function(e){ + this._backoff(); + this._finishInit(e); + }), + timeout: this.expectedNetworkDelay + }; + + if(bargs){ + dojo.mixin(bindArgs, bargs); + } + this._props = props; + for(var tname in this._subscriptions){ + for(var sub in this._subscriptions[tname]){ + if(this._subscriptions[tname][sub].topic){ + dojo.unsubscribe(this._subscriptions[tname][sub].topic); + } + } + } + this._messageQ = []; + this._subscriptions = []; + this._initialized = true; + this._status = "handshaking"; + this.batch = 0; + this.startBatch(); + + var r; + // if xdomain, then we assume jsonp for handshake + if(this._isXD){ + bindArgs.callbackParamName = "jsonp"; + r = dojo.io.script.get(bindArgs); + }else{ + r = dojo.xhrPost(bindArgs); + } + return r; + } + + this.publish = function(/*String*/ channel, /*Object*/ data, /*Object?*/ props){ + // summary: + // publishes the passed message to the cometd server for delivery + // on the specified topic + // channel: + // the destination channel for the message + // data: + // a JSON object containing the message "payload" + // properties: + // Optional. Other meta-data to be mixed into the top-level of the + // message + var message = { + data: data, + channel: channel + }; + if(props){ + dojo.mixin(message, props); + } + this._sendMessage(message); + } + + + this.subscribe = function( /*String */ channel, + /*Object */ objOrFunc, + /*String */ funcName, + /*Object?*/ props){ // return: dojo.Deferred + // summary: + // inform the server of this client's interest in channel + // description: + // `dojox.cometd.subscribe()` handles all the hard work of telling + // the server that we want to be notified when events are + // published on a particular topic. `subscribe` accepts a function + // to handle messages and returns a `dojo.Deferred` object which + // has an extra property added to it which makes it suitable for + // passing to `dojox.cometd.unsubscribe()` as a "subscription + // handle" (much like the handle object that `dojo.connect()` + // produces and which `dojo.disconnect()` expects). + // + // Note that of a subscription is registered before a connection + // with the server is established, events sent before the + // connection is established will not be delivered to this client. + // The deferred object which `subscribe` returns will callback + // when the server successfuly acknolwedges receipt of our + // "subscribe" request. + // channel: + // name of the cometd channel to subscribe to + // objOrFunc: + // an object scope for funcName or the name or reference to a + // function to be called when messages are delivered to the + // channel + // funcName: + // the second half of the objOrFunc/funcName pair for identifying + // a callback function to notifiy upon channel message delivery + // example: + // Simple subscribe use-case + // | dojox.cometd.init("http://myserver.com:8080/cometd"); + // | // log out all incoming messages on /foo/bar + // | dojox.cometd.subscribe("/foo/bar", console, "debug"); + // example: + // Subscribe before connection is initialized + // | dojox.cometd.subscribe("/foo/bar", console, "debug"); + // | dojox.cometd.init("http://myserver.com:8080/cometd"); + // example: + // Subscribe an unsubscribe + // | dojox.cometd.init("http://myserver.com:8080/cometd"); + // | var h = dojox.cometd.subscribe("/foo/bar", console, "debug"); + // | dojox.cometd.unsubscribe(h); + // example: + // Listen for successful subscription: + // | dojox.cometd.init("http://myserver.com:8080/cometd"); + // | var h = dojox.cometd.subscribe("/foo/bar", console, "debug"); + // | h.addCallback(function(){ + // | console.debug("subscription to /foo/bar established"); + // | }); + + props = props||{}; + if(objOrFunc){ + var tname = prefix + channel; + var subs = this._subscriptions[tname]; + if(!subs || subs.length == 0){ + subs = []; + props.channel = "/meta/subscribe"; + props.subscription = channel; + this._sendMessage(props); + + var _ds = this._deferredSubscribes; + if(_ds[channel]){ + _ds[channel].cancel(); + delete _ds[channel]; + } + _ds[channel] = new dojo.Deferred(); + } + + for(var i in subs){ + if(subs[i].objOrFunc === objOrFunc && (!subs[i].funcName&&!funcName||subs[i].funcName==funcName) ){ + return null; + } + } + + var topic = dojo.subscribe(tname, objOrFunc, funcName); + subs.push({ + topic: topic, + objOrFunc: objOrFunc, + funcName: funcName + }); + this._subscriptions[tname] = subs; + } + var ret = this._deferredSubscribes[channel] || {}; + ret.args = dojo._toArray(arguments); + return ret; // dojo.Deferred + } + + this.unsubscribe = function( /*String*/ channel, + /*Object?*/ objOrFunc, + /*String?*/ funcName, + /*Object?*/ props){ + // summary: + // inform the server of this client's disinterest in channel + // channel: + // name of the cometd channel to unsubscribe from + // objOrFunc: + // an object scope for funcName or the name or reference to a + // function to be called when messages are delivered to the + // channel. If null then all subscribers to the channel are unsubscribed. + // funcName: + // the second half of the objOrFunc/funcName pair for identifying + // a callback function to notifiy upon channel message delivery + + if( + (arguments.length == 1) && + (!dojo.isString(channel)) && + (channel.args) + ){ + // it's a subscription handle, unroll + return this.unsubscribe.apply(this, channel.args); + } + + var tname = prefix + channel; + var subs = this._subscriptions[tname]; + if(!subs || subs.length==0){ + return null; + } + + var s=0; + for(var i in subs){ + var sb = subs[i]; + if((!objOrFunc) || + ( + sb.objOrFunc===objOrFunc && + (!sb.funcName && !funcName || sb.funcName==funcName) + ) + ){ + dojo.unsubscribe(subs[i].topic); + delete subs[i]; + }else{ + s++; + } + } + + if(s == 0){ + props = props || {}; + props.channel = "/meta/unsubscribe"; + props.subscription = channel; + delete this._subscriptions[tname]; + this._sendMessage(props); + this._deferredUnsubscribes[channel] = new dojo.Deferred(); + if(this._deferredSubscribes[channel]){ + this._deferredSubscribes[channel].cancel(); + delete this._deferredSubscribes[channel]; + } + } + return this._deferredUnsubscribes[channel]; // dojo.Deferred + } + + + this.disconnect = function(){ + // summary: + // Disconnect from the server. + // description: + // Disconnect from the server by sending a disconnect message + // example: + // | dojox.cometd.disconnect(); + + for(var tname in this._subscriptions){ + for(var sub in this._subscriptions[tname]){ + if(this._subscriptions[tname][sub].topic){ + dojo.unsubscribe(this._subscriptions[tname][sub].topic); + } + } + } + this._subscriptions = []; + this._messageQ = []; + if(this._initialized && this.currentTransport){ + this._initialized=false; + this.currentTransport.disconnect(); + } + if(!this._polling) { + this._publishMeta("connect",false); + } + this._initialized=false; + this._handshook=false; + this._status = "disconnected"; //should be disconnecting, but we ignore the reply to this message + this._publishMeta("disconnect",true); + } + + + // public extension points + + this.subscribed = function( /*String*/channel, /*Object*/message){ } + + this.unsubscribed = function(/*String*/channel, /*Object*/message){ } + + + // private methods (TODO name all with leading _) + + this.tunnelInit = function(childLocation, childDomain){ + // placeholder - replaced by _finishInit + } + + this.tunnelCollapse = function(){ + // placeholder - replaced by _finishInit + } + + this._backoff = function(){ + if(!this._advice){ + this._advice={reconnect:"retry",interval:0}; + }else if(!this._advice.interval){ + this._advice.interval = 0; + } + + if(this._backoffInterval < this._backoffMax){ + this._backoffInterval += this._backoffIncrement; + } + } + + this._backon = function(){ + this._backoffInterval=0; + } + + this._interval = function(){ + var i = this._backoffInterval + (this._advice ? (this._advice.interval ? this._advice.interval : 0) : 0); + if (i>0){ + console.log("Retry in interval+backoff=" + this._advice.interval + "+" + this._backoffInterval+"="+i+"ms"); + } + return i; + } + + this._publishMeta = function(action,successful,props){ + try { + var meta = {cometd:this,action:action,successful:successful,state:this.state()}; + if (props){ + dojo.mixin(meta, props); + } + dojo.publish(this.prefix + "/meta", [meta]); + } catch(e) { + console.log(e); + } + } + + this._finishInit = function(data){ + // summary: + // Handle the handshake return from the server and initialize + // connection if all is OK + + if(this._status!="handshaking") {return;} + + + var wasHandshook = this._handshook; + var successful = false; + var metaMsg = {}; + + if (data instanceof Error) { + dojo.mixin(metaMsg,{ + reestablish:false, + failure: true, + error: data, + advice: this._advice + }); + } else { + data = data[0]; + data = this._extendIn(data); + this.handshakeReturn = data; + // remember any advice + if(data["advice"]){ + this._advice = data.advice; + } + + successful = data.successful ? data.successful : false; + + // check version + if(data.version < this.minimumVersion){ + if (console.log) + console.log("cometd protocol version mismatch. We wanted", this.minimumVersion, "but got", data.version); + successful=false; + this._advice.reconnect="none"; + } + dojo.mixin(metaMsg,{reestablish: successful && wasHandshook, response:data}); + } + + this._publishMeta("handshake",successful,metaMsg); + //in the meta listeners, disconnect() may have been called, so recheck it now to + //prevent resends or continuing with initializing the protocol + if(this._status!="handshaking") {return;} + + // If all OK + if(successful){ + this._status = "connecting"; + this._handshook = true; + // pick a transport + this.currentTransport = dojox.cometd.connectionTypes.match( + data.supportedConnectionTypes, + data.version, + this._isXD + ); + var transport = this.currentTransport; + // initialize the transport + transport._cometd = this; + transport.version = data.version; + this.clientId = data.clientId; + this.tunnelInit = transport.tunnelInit && dojo.hitch(transport, "tunnelInit"); + this.tunnelCollapse = transport.tunnelCollapse && dojo.hitch(transport, "tunnelCollapse"); + transport.startup(data); + }else{ + // If there is a problem follow advice + if(!this._advice || this._advice["reconnect"] != "none"){ + setTimeout(dojo.hitch(this, "init", this.url, this._props), this._interval()); + } + } + } + + // FIXME: lots of repeated code...why? + this._extendIn = function(message){ + // summary: Handle extensions for inbound messages + dojo.forEach(dojox.cometd._extendInList, function(f){ + message = f(message) || message; + }); + return message; + } + + this._extendOut = function(message){ + // summary: Handle extensions for inbound messages + dojo.forEach(dojox.cometd._extendOutList, function(f){ + message = f(message) || message; + }); + return message; + } + + this.deliver = function(messages){ + dojo.forEach(messages, this._deliver, this); + return messages; + } + + this._deliver = function(message){ + // dipatch events along the specified path + + message = this._extendIn(message); + + if(!message["channel"]){ + if(message["success"] !== true){ + return; + } + } + this.lastMessage = message; + + if(message.advice){ + this._advice = message.advice; // TODO maybe merge? + } + + // check to see if we got a /meta channel message that we care about + var deferred=null; + if( (message["channel"]) && + (message.channel.length > 5) && + (message.channel.substr(0, 5) == "/meta")){ + // check for various meta topic actions that we need to respond to + switch(message.channel){ + case "/meta/connect": + var metaMsg = {response: message}; + if(message.successful) { + if (this._status != "connected"){ + this._status = "connected"; + this.endBatch(); + } + } + + if(this._initialized){ + this._publishMeta("connect",message.successful, metaMsg); + } + break; + case "/meta/subscribe": + deferred = this._deferredSubscribes[message.subscription]; + try + { + if(!message.successful){ + if(deferred){ + deferred.errback(new Error(message.error)); + } + this.currentTransport.cancelConnect(); + return; + } + if(deferred){ + deferred.callback(true); + } + this.subscribed(message.subscription, message); + } catch(e) { + log.warn(e); + } + break; + case "/meta/unsubscribe": + deferred = this._deferredUnsubscribes[message.subscription]; + try + { + if(!message.successful){ + if(deferred){ + deferred.errback(new Error(message.error)); + } + this.currentTransport.cancelConnect(); + return; + } + if(deferred){ + deferred.callback(true); + } + this.unsubscribed(message.subscription, message); + } catch(e) { + log.warn(e); + } + break; + default: + if(message.successful && !message.successful){ + this.currentTransport.cancelConnect(); + return; + } + } + } + + // send the message down for processing by the transport + this.currentTransport.deliver(message); + + if(message.data){ + // dispatch the message to any locally subscribed listeners + try{ + var messages = [message]; + + // Determine target topic + var tname = prefix + message.channel; + + // Deliver to globs that apply to target topic + var tnameParts = message.channel.split("/"); + var tnameGlob = prefix; + for (var i = 1; i < tnameParts.length - 1; i++){ + dojo.publish(tnameGlob + "/**", messages); + tnameGlob += "/" + tnameParts[i]; + } + dojo.publish(tnameGlob + "/**", messages); + dojo.publish(tnameGlob + "/*", messages); + + // deliver to target topic + dojo.publish(tname,messages); + }catch(e){ + console.log(e); + } + } + } + + this._sendMessage = function(/* object */ message){ + if(this.currentTransport && !this.batch){ + return this.currentTransport.sendMessages([message]); + }else{ + this._messageQ.push(message); + return null; + } + } + + this.startBatch = function(){ + this.batch++; + } + + this.endBatch = function(){ + if(--this.batch <= 0 && this.currentTransport && this._status == "connected"){ + this.batch = 0; + var messages = this._messageQ; + this._messageQ = []; + if(messages.length > 0){ + this.currentTransport.sendMessages(messages); + } + } + } + + this._onUnload = function(){ + // make this the last of the onUnload method + dojo.addOnUnload(dojox.cometd, "disconnect"); + } + + this._connectTimeout = function(){ + // summary: Return the connect timeout in ms, calculated as the minimum of the advised timeout + // and the configured timeout. Else 0 to indicate no client side timeout + var advised=0; + if(this._advice && this._advice.timeout && this.expectedNetworkDelay > 0){ + advised = this._advice.timeout + this.expectedNetworkDelay; + } + + if(this.connectTimeout > 0 && this.connectTimeout < advised){ + return this.connectTimeout; + } + + return advised; + } + }, + // connectionTypes are shared by all cometd Connection. + connectionTypes : new dojo.AdapterRegistry(true) +} + +// create the default instance +dojox.cometd.Connection.call(dojox.cometd,"/cometd"); + +/* + +FIXME: TODOC: this info should be part of the relevant functions and/or overview so +the parser can find it. + +transport objects MUST expose the following methods: + - check + - startup + - sendMessages + - deliver + - disconnect +optional, standard but transport dependent methods are: + - tunnelCollapse + - tunnelInit + +Transports SHOULD be namespaced under the cometd object and transports MUST +register themselves with cometd.connectionTypes + +here's a stub transport defintion: + +cometd.blahTransport = new function(){ + this._connectionType="my-polling"; + this._cometd=null; + this.lastTimestamp = null; + + this.check = function(types, version, xdomain){ + // summary: + // determines whether or not this transport is suitable given a + // list of transport types that the server supports + return dojo.inArray(types, "blah"); + } + + this.startup = function(){ + if(dojox.cometd._polling){ return; } + // FIXME: fill in startup routine here + dojox.cometd._polling = true; + } + + this.sendMessages = function(message){ + // FIXME: fill in message array sending logic + } + + this.deliver = function(message){ + } + + this.disconnect = function(){ + // send orderly disconnect message + } + + this.cancelConnect = function(){ + // cancel the current connection + } +} +cometd.connectionTypes.register("blah", cometd.blahTransport.check, cometd.blahTransport); +*/ + +dojo.addOnUnload(dojox.cometd, "_onUnload"); + +}); diff --git a/js/dojo-1.7.2/dojox/cometd/ack.js b/js/dojo-1.7.2/dojox/cometd/ack.js new file mode 100644 index 0000000..95e7617 --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/ack.js @@ -0,0 +1,55 @@ +//>>built +// wrapped by build app +define("dojox/cometd/ack", ["dijit","dojo","dojox","dojo/require!dojox/cometd/_base"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.ack"); +dojo.require("dojox.cometd._base"); + +/* + * This file provides the dojox cometd ack extension which + * acknowledges the messages received in /meta/connect responses. + * Each meta/connect is sent with the id of the last successful meta/connect + * received. The server uses this information to manage a queue of unacknowleged + * messages. + * + * To use, add dojo.require("dojox.cometd.ack"); and if the handshake will be sent + * with ext:{ack:true}. If the server supports the same extension, then the + * mechanism will be initialized. The dojox.cometd.ackEnabled field may also be + * used to optionally enable/disable the extension before init of cometd. + * + */ +dojox.cometd._ack = new function(){ + var supportAcks = false; + var lastAck = -1; + + this._in = function(msg){ + if (msg.channel == "/meta/handshake") { + supportAcks = msg.ext && msg.ext.ack; + } else if (supportAcks && msg.channel == "/meta/connect" && msg.ext && msg.ext.ack && msg.successful) { + var ackId = parseInt(msg.ext.ack); + lastAck = ackId; + } + return msg; + } + + this._out = function(msg){ + + if (msg.channel == "/meta/handshake") { + if (!msg.ext) + msg.ext = {}; + msg.ext.ack = dojox.cometd.ackEnabled; + lastAck = -1; + } + if (supportAcks && msg.channel == "/meta/connect") { + if (!msg.ext) + msg.ext = {}; + msg.ext.ack = lastAck; + } + return msg; + } +}; + +dojox.cometd._extendInList.push(dojo.hitch(dojox.cometd._ack, "_in")); +dojox.cometd._extendOutList.push(dojo.hitch(dojox.cometd._ack, "_out")); +dojox.cometd.ackEnabled = true; + +}); diff --git a/js/dojo-1.7.2/dojox/cometd/callbackPollTransport.js b/js/dojo-1.7.2/dojox/cometd/callbackPollTransport.js new file mode 100644 index 0000000..25e7152 --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/callbackPollTransport.js @@ -0,0 +1,107 @@ +//>>built +// wrapped by build app +define("dojox/cometd/callbackPollTransport", ["dijit","dojo","dojox","dojo/require!dojox/cometd/_base,dojox/cometd/longPollTransport,dojo/io/script"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.callbackPollTransport"); +dojo.require("dojox.cometd._base"); +dojo.require("dojox.cometd.longPollTransport"); +dojo.require("dojo.io.script"); + +dojox.cometd.callbackPollTransport = new function(){ + + this._connectionType = "callback-polling"; + this._cometd = null; + + this.check = function(types, version, xdomain){ + // we handle x-domain! + return (dojo.indexOf(types, "callback-polling") >= 0); + } + + this.tunnelInit = function(){ + var message = { + channel: "/meta/connect", + clientId: this._cometd.clientId, + connectionType: this._connectionType, + id: "" + this._cometd.messageId++ + }; + message = this._cometd._extendOut(message); + this.openTunnelWith([message]); + } + + this.tunnelCollapse = dojox.cometd.longPollTransport.tunnelCollapse; + this._connect = dojox.cometd.longPollTransport._connect; + this.deliver = dojox.cometd.longPollTransport.deliver; + + this.openTunnelWith = function(content, url){ + this._cometd._polling = true; + var script = { + load: dojo.hitch(this, function(data){ + this._cometd._polling=false; + this._cometd.deliver(data); + this._cometd._backon(); + this.tunnelCollapse(); + }), + error: dojo.hitch(this, function(err){ + this._cometd._polling = false; + this._cometd._publishMeta("connect",false); + this._cometd._backoff(); + this.tunnelCollapse(); + }), + url: (url || this._cometd.url), + content: { message: dojo.toJson(content) }, + callbackParamName: "jsonp" + }; + var connectTimeout = this._cometd._connectTimeout(); + if(connectTimeout > 0){ + script.timeout=connectTimeout; + } + dojo.io.script.get(script); + } + + this.sendMessages = function(/*array*/ messages){ + for(var i = 0; i < messages.length; i++){ + messages[i].clientId = this._cometd.clientId; + messages[i].id = ""+this._cometd.messageId++; + messages[i]=this._cometd._extendOut(messages[i]); + } + + var bindArgs = { + url: this._cometd.url || dojo.config["cometdRoot"], + load: dojo.hitch(this._cometd, "deliver"), + callbackParamName: "jsonp", + content: { message: dojo.toJson( messages ) }, + error: dojo.hitch(this, function(err){ + this._cometd._publishMeta("publish",false,{messages:messages}); + }), + timeout: this._cometd.expectedNetworkDelay + }; + return dojo.io.script.get(bindArgs); + } + + this.startup = function(handshakeData){ + if(this._cometd._connected){ return; } + this.tunnelInit(); + } + + // FIXME: what is this supposed to do? ;) + this.disconnect = dojox.cometd.longPollTransport.disconnect; + this.disconnect = function(){ + var message = { + channel: "/meta/disconnect", + clientId: this._cometd.clientId, + id: "" + this._cometd.messageId++ + }; + message = this._cometd._extendOut(message); + dojo.io.script.get({ + url: this._cometd.url || dojo.config["cometdRoot"], + callbackParamName: "jsonp", + content: { message: dojo.toJson([message]) } + }); + } + + this.cancelConnect = function(){} +} + +dojox.cometd.connectionTypes.register("callback-polling", dojox.cometd.callbackPollTransport.check, dojox.cometd.callbackPollTransport); + + +}); diff --git a/js/dojo-1.7.2/dojox/cometd/longPollTransport.js b/js/dojo-1.7.2/dojox/cometd/longPollTransport.js new file mode 100644 index 0000000..9d2d6fc --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/longPollTransport.js @@ -0,0 +1,7 @@ +//>>built +// wrapped by build app +define("dojox/cometd/longPollTransport", ["dijit","dojo","dojox","dojo/require!dojox/cometd/longPollTransportJsonEncoded"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.longPollTransport"); +dojo.require("dojox.cometd.longPollTransportJsonEncoded"); + +}); diff --git a/js/dojo-1.7.2/dojox/cometd/longPollTransportFormEncoded.js b/js/dojo-1.7.2/dojox/cometd/longPollTransportFormEncoded.js new file mode 100644 index 0000000..bdad3c9 --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/longPollTransportFormEncoded.js @@ -0,0 +1,162 @@ +//>>built +// wrapped by build app +define("dojox/cometd/longPollTransportFormEncoded", ["dijit","dojo","dojox","dojo/require!dojox/cometd/_base"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.longPollTransportFormEncoded"); +dojo.require("dojox.cometd._base"); + +dojox.cometd.longPollTransportFormEncoded = new function(){ + // This is an alternative implementation to that provided in logPollTransport.js that + // form encodes all messages instead of sending them as text/json + + this._connectionType = "long-polling"; + this._cometd = null; + + this.check = function(types, version, xdomain){ + return ((!xdomain)&&(dojo.indexOf(types, "long-polling") >= 0)); + } + + this.tunnelInit = function(){ + var message = { + channel: "/meta/connect", + clientId: this._cometd.clientId, + connectionType: this._connectionType, + id: "" + this._cometd.messageId++ + }; + message = this._cometd._extendOut(message); + this.openTunnelWith({ message: dojo.toJson([message]) }); + } + + this.tunnelCollapse = function(){ + // TODO handle transport specific advice + + if(!this._cometd._initialized){ return; } + if(this._cometd._advice && this._cometd._advice["reconnect"]=="none"){ + return; + } + var interval = this._cometd._interval(); + if (this._cometd._status=="connected") { + setTimeout(dojo.hitch(this, "_connect"), interval); + }else{ + setTimeout(dojo.hitch(this._cometd, function(){ + this.init(this.url, this._props); + }), interval); + } + } + + this._connect = function(){ + if(!this._cometd._initialized){ return; } + if(this._cometd._polling) { return; } + + if((this._cometd._advice) && (this._cometd._advice["reconnect"]=="handshake")){ + this._cometd._status="unconnected"; //? + this._initialized = false; + this._cometd.init(this._cometd.url, this._cometd._props); + }else if(this._cometd._status=="connected"){ + var message = { + channel: "/meta/connect", + connectionType: this._connectionType, + clientId: this._cometd.clientId, + id: "" + this._cometd.messageId++ + }; + if(this._cometd.connectTimeout>=this._cometd.expectedNetworkDelay){ + message.advice = { + timeout: this._cometd.connectTimeout - this._cometd.expectedNetworkDelay + }; + } + message = this._cometd._extendOut(message); + this.openTunnelWith({ message: dojo.toJson([message]) }); + } + } + + this.deliver = function(message){ + // Nothing to do + } + + this.openTunnelWith = function(content, url){ + this._cometd._polling = true; + var post = { + url: (url||this._cometd.url), + content: content, + handleAs: this._cometd.handleAs, + load: dojo.hitch(this, function(data){ + this._cometd._polling=false; + this._cometd.deliver(data); + this._cometd._backon(); + this.tunnelCollapse(); + }), + error: dojo.hitch(this, function(err){ + var metaMsg = { + failure: true, + error: err, + advice: this._cometd._advice + }; + this._cometd._polling=false; + this._cometd._publishMeta("connect",false, metaMsg); + this._cometd._backoff(); + this.tunnelCollapse(); + }) + }; + + var connectTimeout = this._cometd._connectTimeout(); + if(connectTimeout > 0){ + post.timeout = connectTimeout; + } + + this._poll = dojo.xhrPost(post); + } + + this.sendMessages = function(messages){ + for(var i=0; i < messages.length; i++){ + messages[i].clientId = this._cometd.clientId; + messages[i].id = "" + this._cometd.messageId++; + messages[i]= this._cometd._extendOut(messages[i]); + } + return dojo.xhrPost({ + url: this._cometd.url||dojo.config["cometdRoot"], + handleAs: this._cometd.handleAs, + load: dojo.hitch(this._cometd, "deliver"), + content: { message: dojo.toJson(messages) }, + error: dojo.hitch(this, function(err){ + this._cometd._publishMeta("publish",false,{messages:messages}); + }), + timeout: this._cometd.expectedNetworkDelay + }); + } + + this.startup = function(handshakeData){ + if(this._cometd._status=="connected"){ return; } + this.tunnelInit(); + } + + this.disconnect = function(){ + var message = { + channel: "/meta/disconnect", + clientId: this._cometd.clientId, + id: "" + this._cometd.messageId++ + }; + message = this._cometd._extendOut(message); + dojo.xhrPost({ + url: this._cometd.url || dojo.config["cometdRoot"], + handleAs: this._cometd.handleAs, + content: { message: dojo.toJson([message]) } + }); + } + + this.cancelConnect = function(){ + if(this._poll){ + this._poll.cancel(); + this._cometd._polling=false; + this._cometd._publishMeta("connect",false,{cancel:true}); + this._cometd._backoff(); + this.disconnect(); + this.tunnelCollapse(); + } + } +} + +dojox.cometd.longPollTransport = dojox.cometd.longPollTransportFormEncoded; + +dojox.cometd.connectionTypes.register("long-polling", dojox.cometd.longPollTransport.check, dojox.cometd.longPollTransportFormEncoded); +dojox.cometd.connectionTypes.register("long-polling-form-encoded", dojox.cometd.longPollTransport.check, dojox.cometd.longPollTransportFormEncoded); + +}); diff --git a/js/dojo-1.7.2/dojox/cometd/longPollTransportJsonEncoded.js b/js/dojo-1.7.2/dojox/cometd/longPollTransportJsonEncoded.js new file mode 100644 index 0000000..8a068c8 --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/longPollTransportJsonEncoded.js @@ -0,0 +1,164 @@ +//>>built +// wrapped by build app +define("dojox/cometd/longPollTransportJsonEncoded", ["dijit","dojo","dojox","dojo/require!dojox/cometd/_base"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.longPollTransportJsonEncoded"); +dojo.require("dojox.cometd._base"); + +dojox.cometd.longPollTransportJsonEncoded = new function(){ + // This is an alternative implementation to that provided in logPollTransportFormEncoded.js + // that sends messages as text/json rather than form encoding them. + + this._connectionType="long-polling"; + this._cometd=null; + + this.check = function(types, version, xdomain){ + return ((!xdomain)&&(dojo.indexOf(types, "long-polling") >= 0)); + } + + this.tunnelInit = function(){ + var message = { + channel: "/meta/connect", + clientId: this._cometd.clientId, + connectionType: this._connectionType, + id: ""+this._cometd.messageId++ + }; + message=this._cometd._extendOut(message); + this.openTunnelWith([message]); + } + + this.tunnelCollapse = function(){ + // TODO handle transport specific advice + + if(!this._cometd._initialized){ return; } + + if(this._cometd._advice && this._cometd._advice["reconnect"]=="none"){ + return; + } + if (this._cometd._status=="connected") { + setTimeout(dojo.hitch(this,function(){this._connect();}),this._cometd._interval()); + }else{ + setTimeout(dojo.hitch(this._cometd,function(){this.init(this.url,this._props);}),this._cometd._interval()); + } + } + + this._connect = function(){ + if(!this._cometd._initialized){ return; } + if(this._cometd._polling) { + return; + } + + if((this._cometd._advice) && (this._cometd._advice["reconnect"]=="handshake")){ + this._cometd._status="unconnected"; + this._initialized = false; + this._cometd.init(this._cometd.url,this._cometd._props); + }else if(this._cometd._status=="connected"){ + var message={ + channel: "/meta/connect", + connectionType: this._connectionType, + clientId: this._cometd.clientId, + id: ""+this._cometd.messageId++ + }; + if (this._cometd.connectTimeout>=this._cometd.expectedNetworkDelay){ + message.advice={timeout:(this._cometd.connectTimeout-this._cometd.expectedNetworkDelay)}; + } + message=this._cometd._extendOut(message); + this.openTunnelWith([message]); + } + } + + this.deliver = function(message){ + // Nothing to do + } + + this.openTunnelWith = function(messages, url){ + this._cometd._polling = true; + var post = { + url: (url||this._cometd.url), + postData: dojo.toJson(messages), + contentType: "text/json;charset=UTF-8", + handleAs: this._cometd.handleAs, + load: dojo.hitch(this, function(data){ + this._cometd._polling=false; + this._cometd.deliver(data); + this._cometd._backon(); + this.tunnelCollapse(); + }), + error: dojo.hitch(this, function(err){ + this._cometd._polling=false; + var metaMsg = { + failure: true, + error: err, + advice: this._cometd._advice + }; + this._cometd._publishMeta("connect",false, metaMsg); + this._cometd._backoff(); + this.tunnelCollapse(); + }) + }; + + var connectTimeout=this._cometd._connectTimeout(); + if (connectTimeout>0) { + post.timeout=connectTimeout; + } + + this._poll = dojo.rawXhrPost(post); + } + + this.sendMessages = function(messages){ + for(var i=0; i<messages.length; i++){ + messages[i].clientId = this._cometd.clientId; + messages[i].id = ""+this._cometd.messageId++; + messages[i]=this._cometd._extendOut(messages[i]); + } + return dojo.rawXhrPost({ + url: this._cometd.url||dojo.config["cometdRoot"], + handleAs: this._cometd.handleAs, + load: dojo.hitch(this._cometd, "deliver"), + postData: dojo.toJson(messages), + contentType: "text/json;charset=UTF-8", + error: dojo.hitch(this, function(err){ + this._cometd._publishMeta("publish",false,{messages:messages}); + }), + timeout: this._cometd.expectedNetworkDelay + }); + } + + this.startup = function(handshakeData){ + if(this._cometd._status=="connected"){ return; } + this.tunnelInit(); + } + + this.disconnect = function(){ + var message = { + channel: "/meta/disconnect", + clientId: this._cometd.clientId, + id: "" + this._cometd.messageId++ + }; + message = this._cometd._extendOut(message); + dojo.rawXhrPost({ + url: this._cometd.url || dojo.config["cometdRoot"], + handleAs: this._cometd.handleAs, + postData: dojo.toJson([message]), + contentType: "text/json;charset=UTF-8" + }); + } + + this.cancelConnect = function(){ + if(this._poll){ + this._poll.cancel(); + this._cometd._polling=false; + this._cometd._publishMeta("connect",false,{cancel:true}); + this._cometd._backoff(); + this.disconnect(); + this.tunnelCollapse(); + } + } +} + +dojox.cometd.longPollTransport = dojox.cometd.longPollTransportJsonEncoded; + +dojox.cometd.connectionTypes.register("long-polling", dojox.cometd.longPollTransport.check, dojox.cometd.longPollTransportJsonEncoded); +dojox.cometd.connectionTypes.register("long-polling-json-encoded", dojox.cometd.longPollTransport.check, dojox.cometd.longPollTransportJsonEncoded); + + +}); diff --git a/js/dojo-1.7.2/dojox/cometd/timestamp.js b/js/dojo-1.7.2/dojox/cometd/timestamp.js new file mode 100644 index 0000000..961b0c5 --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/timestamp.js @@ -0,0 +1,13 @@ +//>>built +// wrapped by build app +define("dojox/cometd/timestamp", ["dijit","dojo","dojox","dojo/require!dojox/cometd/_base"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.timestamp"); +dojo.require("dojox.cometd._base"); + +// A cometd extension that adds a timestamp to every message +dojox.cometd._extendOutList.push(function(msg){ + msg.timestamp = new Date().toUTCString(); + return msg +}); + +}); diff --git a/js/dojo-1.7.2/dojox/cometd/timesync.js b/js/dojo-1.7.2/dojox/cometd/timesync.js new file mode 100644 index 0000000..586f65d --- /dev/null +++ b/js/dojo-1.7.2/dojox/cometd/timesync.js @@ -0,0 +1,146 @@ +//>>built +// wrapped by build app +define("dojox/cometd/timesync", ["dijit","dojo","dojox","dojo/require!dojox/cometd/_base"], function(dijit,dojo,dojox){ +dojo.provide("dojox.cometd.timesync"); +dojo.require("dojox.cometd._base"); + +/** + * 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: <code>{ext:{timesync:{tc:12345567890,l:23,o:4567},...},...}</code> + * where:<ul> + * <li>tc is the client timestamp in ms since 1970 of when the message was sent. + * <li>l is the network lag that the client has calculated. + * <li>o is the clock offset that the client has calculated. + * </ul> + * 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. + * <p> + * A cometd 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: <code>{ext:{timesync:{tc:12345567890,ts:1234567900,p:123,a:3},...},...}</code> + * where:<ul> + * <li>tc is the client timestamp of when the message was sent, + * <li>ts is the server timestamp of when the message was received + * <li>p is the poll duration in ms - ie the time the server took before sending the response. + * <li>a is the measured accuracy of the calculated offset and lag sent by the client + * </ul> + * + * 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 measured accuracy is used to adjust the assumption + * that the network is symmetric for traversal time, so: <ul> + * <li>lag = (now-tc-p)/2-a + * <li>offset = ts-tc-lag + * </ul> + * + * 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._lags = []; // The samples used to calculate the average lag. + this._offsets = []; // The samples used to calculate the average offset. + this.lag=0; // The calculated network lag from client to server + this.offset = 0; // The offset in ms between the clients clock and the servers clock. + 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(); + var l=(now-sync.tc-sync.p)/2-sync.a; + var o=sync.ts-sync.tc-l; + + this._lags.push(l); + this._offsets.push(o); + if(this._offsets.length > this._window){ + this._offsets.shift(); + this._lags.shift(); + } + this.samples++; + l=0; + o=0; + for(var i in this._offsets){ + l+=this._lags[i]; + o+=this._offsets[i]; + } + this.offset = parseInt((o / this._offsets.length).toFixed()); + this.lag = parseInt((l / this._lags.length).toFixed()); + + } + } + return msg; + } + + this._out = function(msg){ + // Summary: + // Handle outgoing messages for the timesync extension. + // description: + // Look for handshake and connect messages and add the ext:{timesync:{}} fields + // msg: + // The outgoing bayeux message + + var channel = msg.channel; + if(channel && channel.indexOf('/meta/') == 0){ + var now = new Date().getTime(); + if(!msg.ext){ + msg.ext = {}; + } + msg.ext.timesync = {tc:now,l:this.lag,o:this.offset}; + } + return msg; + } +}; + +dojox.cometd._extendInList.push(dojo.hitch(dojox.cometd.timesync, "_in")); +dojox.cometd._extendOutList.push(dojo.hitch(dojox.cometd.timesync, "_out")); + +}); |
