6 minimumVersion: '0.9',
\r
7 channel: '/meta/handshake'
\r
10 var oTransport = function()
\r
13 (($.comet._sUrl.substring(0,4) == 'http') && ($.comet._sUrl.substr(7,location.href.length).replace(/\/.*/, '') != location.host))
\r
18 this.connectionType = (this._bXD) ? 'callback-polling' : 'long-polling';
\r
20 this.startup = function(oReturn)
\r
22 if(this._comet._bConnected) return;
\r
26 this.tunnelInit = function()
\r
30 channel: '/meta/connect',
\r
31 clientId: $.comet.clientId,
\r
32 id: String($.comet._nNextId++),
\r
33 connectionType: $.comet._oTransport.connectionType
\r
36 this.openTunnel(msgConnect);
\r
39 this.openTunnel = function(oMsg)
\r
41 $.comet._bPolling = true;
\r
43 this._send($.comet._sUrl, oMsg, function(sReturn)
\r
45 var oReturn = (typeof sReturn != "object") ? (eval('(' + sReturn + ')')) : sReturn;
\r
46 $.comet._bPolling = false;
\r
47 $.comet.deliver(oReturn);
\r
48 $.comet._oTransport.closeTunnel();
\r
52 this.closeTunnel = function()
\r
54 if(!$.comet._bInitialized) return;
\r
58 if($.comet._advice.reconnect == 'none') return;
\r
60 if($.comet._advice.interval > 0)
\r
62 setTimeout($.comet._oTransport._connect, $.comet._advice.interval);
\r
66 $.comet._oTransport._connect();
\r
71 $.comet._oTransport._connect();
\r
75 this._connect = function()
\r
77 if(!$.comet._bInitialized) return;
\r
79 if($.comet._bPolling) return;
\r
81 if($.comet._advice && $.comet._advice.reconnect == 'handshake')
\r
83 $.comet._bConnected = false;
\r
84 $.comet.init($.comet._sUrl);
\r
86 else if($.comet._bConnected)
\r
91 clientId: $.comet.clientId,
\r
92 id: String($.comet._nNextId++),
\r
93 channel: '/meta/connect',
\r
94 connectionType: $.comet._oTransport.connectionType
\r
96 $.comet._oTransport.openTunnel(msgConnect);
\r
100 this._send = function(sUrl, oMsg, fCallback) {
\r
101 //default callback will check advice, deliver messages, and reconnect
\r
102 var fCallback = (fCallback) ? fCallback : function(sReturn)
\r
104 var oReturn = (typeof sReturn != "object") ? (eval('(' + sReturn + ')')) : sReturn;
\r
106 $.comet.deliver(oReturn);
\r
108 if($.comet._advice)
\r
110 if($.comet._advice.reconnect == 'none')
\r
113 if($.comet._advice.interval > 0)
\r
115 setTimeout($.comet._oTransport._connect, $.comet._advice.interval);
\r
119 $.comet._oTransport._connect();
\r
124 $.comet._oTransport._connect();
\r
128 //regular AJAX for same domain calls
\r
129 if((!this._bXD) && (this.connectionType == 'long-polling'))
\r
131 this._pollRequest = $.ajax({
\r
134 beforeSend: function(oXhr) { oXhr.setRequestHeader('Connection', 'Keep-Alive'); },
\r
135 data: { message: JSON.stringify(oMsg) },
\r
139 else // JSONP callback for cross domain
\r
141 this._pollRequest = $.ajax({
\r
145 beforeSend: function(oXhr) { oXhr.setRequestHeader('Connection', 'Keep-Alive'); },
\r
148 message: JSON.stringify($.extend(oMsg,{connectionType: 'callback-polling' }))
\r
156 $.comet = new function()
\r
158 this.CONNECTED = 'CONNECTED';
\r
159 this.CONNECTING = 'CONNECTING';
\r
160 this.DISCONNECTED = 'DISCONNECTED';
\r
161 this.DISCONNECTING = 'DISCONNECTING';
\r
163 this._aMessageQueue = [];
\r
164 this._aSubscriptions = [];
\r
165 this._aSubscriptionCallbacks = [];
\r
166 this._bInitialized = false;
\r
167 this._bConnected = false;
\r
170 // just define the transport, do not assign it yet.
\r
171 this._oTransport = ''; //oTransport;
\r
174 this.supportedConectionTypes = [ 'long-polling', 'callback-polling' ];
\r
176 this.clientId = '';
\r
178 this._bTrigger = true; // this sends $.event.trigger(channel, data)
\r
180 this.init = function(sUrl)
\r
182 this._sUrl = (sUrl) ? sUrl : '/cometd';
\r
184 this._oTransport = new oTransport();
\r
186 this._aMessageQueue = [];
\r
187 this._aSubscriptions = [];
\r
188 this._bInitialized = true;
\r
191 var oMsg = $.extend(msgHandshake, {id: String(this._nNextId++)});
\r
193 this._oTransport._send(this._sUrl, oMsg, $.comet._finishInit);
\r
196 this._finishInit = function(sReturn)
\r
198 var oReturn = (typeof sReturn != "object") ? (eval('(' + sReturn + ')')[0]) : sReturn[0];
\r
201 $.comet._advice = oReturn.advice;
\r
203 var bSuccess = (oReturn.successful) ? oReturn.successful : false;
\r
204 // do version check
\r
208 // pick transport ?
\r
211 $.comet._oTransport._comet = $.comet;
\r
212 $.comet._oTransport.version = $.comet.version;
\r
214 $.comet.clientId = oReturn.clientId;
\r
215 $.comet._oTransport.startup(oReturn);
\r
216 $.comet.endBatch();
\r
220 this._sendMessage = function(oMsg)
\r
222 if($.comet._nBatch <= 0)
\r
224 if(oMsg.length > 0)
\r
227 oMsg[i].clientId = String($.comet.clientId);
\r
228 oMsg[i].id = String($.comet._nNextId++);
\r
232 oMsg.clientId = String($.comet.clientId);
\r
233 oMsg.id = String($.comet._nNextId++);
\r
236 $.comet._oTransport._send($.comet._sUrl, oMsg);
\r
240 $.comet._aMessageQueue.push(oMsg);
\r
245 this.startBatch = function() { this._nBatch++ };
\r
246 this.endBatch = function() {
\r
247 if(--this._nBatch <= 0)
\r
250 if(this._aMessageQueue.length > 0)
\r
252 this._sendMessage(this._aMessageQueue);
\r
253 this._aMessageQueue = [];
\r
258 this.subscribe = function(sSubscription, fCallback)
\r
260 // if this topic has not been subscribed to yet, send the message now
\r
261 if(!this._aSubscriptions[sSubscription])
\r
263 this._aSubscriptions.push(sSubscription)
\r
266 this._aSubscriptionCallbacks[sSubscription] = fCallback;
\r
269 this._sendMessage({ channel: '/meta/subscribe', subscription: sSubscription });
\r
272 //$.event.add(window, sSubscription, fCallback);
\r
275 this.unsubscribe = function(sSubscription) {
\r
276 $.comet._sendMessage({ channel: '/meta/unsubscribe', subscription: sSubscription });
\r
279 this.publish = function(sChannel, oData)
\r
281 $.comet._sendMessage({channel: sChannel, data: oData});
\r
284 this.deliver = function(sReturn)
\r
286 var oReturn = sReturn;//eval(sReturn);
\r
288 $(oReturn).each(function()
\r
290 $.comet._deliver(this);
\r
294 this.disconnect = function()
\r
296 $($.comet._aSubscriptions).each(function(i)
\r
298 $.comet.unsubscribe($.comet._aSubscriptions[i]);
\r
301 $.comet._sendMessage({channel:'/meta/disconnect'});
\r
303 $.comet._bInitialized = false;
\r
306 this._deliver = function(oMsg,oData)
\r
310 $.comet._advice = oMsg.advice;
\r
313 switch(oMsg.channel)
\r
315 case '/meta/connect':
\r
316 if(oMsg.successful && !$.comet._bConnected)
\r
318 $.comet._bConnected = $.comet._bInitialized;
\r
319 $.comet.endBatch();
\r
321 $.comet._sendMessage(msgConnect);
\r
326 //$.comet._bConnected = false;
\r
329 // add in subscription handling stuff
\r
330 case '/meta/subscribe':
\r
331 if(!oMsg.successful)
\r
333 $.comet._oTransport._cancelConnect();
\r
338 case '/meta/unsubscribe':
\r
339 if(!oMsg.successful)
\r
341 $.comet._oTransport._cancelConnect();
\r
350 if($.comet._bTrigger)
\r
352 $.event.trigger(oMsg.channel, [oMsg]);
\r
355 var cb = $.comet._aSubscriptionCallbacks[oMsg.channel];
\r