Index: dojo-release-1.3.2-src/dojox/xmpp/TransportSession.js =================================================================== --- dojo-release-1.3.2-src.orig/dojox/xmpp/TransportSession.js 2009-09-16 15:32:33.000000000 -0700 +++ dojo-release-1.3.2-src/dojox/xmpp/TransportSession.js 2009-12-15 16:09:08.625000000 -0800 @@ -10,10 +10,10 @@ dojo.mixin(this, props); if(this.useScriptSrcTransport){ this.transportIframes = []; - - } + } - + } + }; @@ -46,8 +46,8 @@ sendTimeout: (this.wait+20)*1000, useScriptSrcTransport:false, - - + + keepAliveTimer:null, //status @@ -60,6 +60,7 @@ inboundQueue: [], deferredRequests: {}, matchTypeIdAttribute: {}, + lastPacketSentTime:null, open: function() { this.status = "notReady"; @@ -71,15 +72,15 @@ this.deferredRequests = {}; this.matchTypeIdAttribute = {}; - + this.keepAliveTimer = setTimeout(dojo.hitch(this, "_keepAlive"), 10000); - + if(this.useScriptSrcTransport){ - dojo.connect(dojox.xmpp.TransportSession, + dojo.connect(dojox.xmpp.TransportSession, "handleBOSH", this, "processScriptSrc"); - + this.transportIframes = []; - + for(var i = 0; i <= this.hold; i++) { var iframe = dojo.io.iframe.create("xmpp-transport-" + i, dojox._scopeName + ".xmpp.TransportSession._iframeOnload("+i+");" ); this.transportIframes.push(iframe); @@ -87,28 +88,29 @@ dojo.connect(iframe, "onload", this, "_sendLogin"); } } - - + + } else { this._sendLogin(); } }, - - _sendLogin: function() { - var rid = this.rid++; - var req = { - content: this.submitContentType, - hold: this.hold, - rid: rid, - to: this.domain, - secure: this.secure, - wait: this.wait, - "xml:lang": this.lang, - xmlns: dojox.xmpp.xmpp.BODY_NS - }; - var msg = dojox.xmpp.util.createElement("body", req, true); - this.addToOutboundQueue(msg, rid); + _sendLogin: function() { + var rid = this.rid++; + var req = { + content: this.submitContentType, + hold: this.hold, + rid: rid, + to: this.domain, + secure: this.secure, + wait: this.wait, + "xml:lang": this.lang, + xmlns: dojox.xmpp.xmpp.BODY_NS + }; + + var msg = dojox.xmpp.util.createElement("body", req, true); + this.addToOutboundQueue(msg, rid); + this.keepAliveTimer = setTimeout(dojo.hitch(this, "_keepAlive"), 10000); }, processScriptSrc: function(msg, rid) { @@ -123,13 +125,13 @@ //console.log("Recived bad document from server",msg); } }, - + _keepAlive: function(){ if (this.state=="wait" || this.isTerminated()) { return; } - this._dispatchPacket(); this.keepAliveTimer = setTimeout(dojo.hitch(this, "_keepAlive"), 10000); + this._dispatchPacket(); }, @@ -166,9 +168,9 @@ //that allow a deferred to be tied to a protocol response instad of the whole //rid - // //console.log("In dispatchPacket ", msg, protocolMatchType, matchId, matchProperty); + // console.log("In dispatchPacket ", msg, protocolMatchType, matchId, matchProperty); if (msg){ - this.protocolPacketQueue.push(msg); + this.protocolPacketQueue.push(msg); } var def = new dojo.Deferred(); @@ -181,9 +183,9 @@ if(def.matchProperty != "id") { this.matchTypeIdAttribute[protocolMatchType] = def.matchProperty; } + this.deferredRequests[def.protocolMatchType + "-" +def.matchId]=def; } - - this.deferredRequests[def.protocolMatchType + "-" +def.matchId]=def; + if(!this.dispatchTimer) { this.dispatchTimer = setTimeout(dojo.hitch(this, "_dispatchPacket"), 600); } @@ -218,29 +220,38 @@ return; } + //check for max concurrent requests. + var expectedRid = this.rid; + if (this.outboundQueue.length > 0){ + expectedRid = this.outboundQueue[0]["rid"]; + } + //if pending responses from server is more than hold then queue the packet + if (this.rid - expectedRid > this.hold) { + var now = (new Date()).getTime(); + if (now - this.lastPacketSentTime > 1.5*this.wait*1000) { + //The response from server has not been received + //for more than 150% if wait time so probably the request + //is lost so redispatch it + console.log("The last packet was sent before " + (now - this.lastPacketSentTime) + "ms"); + this.redispatchPacket(expectedRid); + } + if(!this.dispatchTimer) { + console.log((this.rid - expectedRid) + " pending requests so queueing the packet"); + this.dispatchTimer = setTimeout(dojo.hitch(this, "_dispatchPacket"), 600); + return; + } + } + var req = { - sid: this.sid + sid: this.sid, + rid: this.rid++ } if (this.protocolPacketQueue.length > 0){ - req.rid= this.rid++; var envelope = new dojox.string.Builder(dojox.xmpp.util.createElement("body", req, false)); envelope.append(this.processProtocolPacketQueue()); envelope.append(""); - delete this.lastPollTime; } else { - //console.log("Nothing to send, I'm just polling."); - if(this.lastPollTime) { - var now = new Date().getTime(); - if(now - this.lastPollTime < this.polling) { - //console.log("Waiting to poll ", this.polling - (now - this.lastPollTime)+10); - this.dispatchTimer = setTimeout(dojo.hitch(this, "_dispatchPacket"), this.polling - (now - this.lastPollTime)+10); - return; - } - - } - req.rid= this.rid++; - this.lastPollTime = new Date().getTime(); var envelope = new dojox.string.Builder(dojox.xmpp.util.createElement("body", req, true)); } @@ -251,8 +262,23 @@ }, redispatchPacket: function(rid){ - var env = this.outboundRequests[rid]; - this.sendXml(env, rid); + while(true) { + var env = this.outboundRequests[rid]; + if (!env) break; + var found = false; + for (var i=0; i element ", doc, " RID: ", rid); + console.log("TransportSession::processDocument() firstChild is not element ", doc, " RID: ", rid); } if (this.outboundQueue.length<1){return;} var expectedId = this.outboundQueue[0]["rid"]; - //console.log("expectedId", expectedId); + if (rid==expectedId){ this.removeFromOutboundQueue(rid); this.processResponse(body, rid); this.processInboundQueue(); - }else{ - //console.log("TransportSession::processDocument() rid: ", rid, " expected: ", expectedId); + }else if (!isInboundQueuedPacket){ + console.log("TransportSession::processDocument() rid: ", rid, " expected: ", expectedId); var gap = rid-expectedId; - + //TODO do possible retransmission here. if (gap < this.hold + 2){ this.addToInboundQueue(doc,rid); }else{ - //console.log("TransportSession::processDocument() RID is outside of the expected response window"); + console.log("TransportSession::processDocument() RID is outside of the expected response window"); } } return doc; }, processInboundQueue: function(){ - while (this.inboundQueue.length > 0) { + if (this.inboundQueue.length > 0) { var item = this.inboundQueue.shift(); - this.processDocument(item["doc"], item["rid"]); + this.processDocument(item["doc"], item["rid"], true); } }, @@ -379,19 +405,21 @@ }, processResponse: function(body,rid){ - ////console.log("TransportSession:processResponse() ", body, " RID: ", rid); + //console.log("TransportSession:processResponse() ", body, " RID: ", rid); if (body.getAttribute("type")=='terminate'){ var reasonNode = body.firstChild.firstChild; var errorMessage = ""; if(reasonNode && reasonNode.nodeName == "conflict") { - errorMessage = "conflict" - } + errorMessage = "conflict" + } this.setState("Terminate", errorMessage); return; } + //TODO if type == error do retransmission, probably would need doc for outbound queue. + if ((this.state != 'Ready')&&(this.state != 'Terminate')) { var sid=body.getAttribute("sid"); if (sid){ @@ -411,7 +439,7 @@ if( body.getAttribute("polling")){ this.polling= parseInt(body.getAttribute("polling"))*1000; } - + //console.log("Polling value ", this.polling); this.inactivity = body.getAttribute("inactivity"); this.setState("Ready");