dojo.provide("dojox.xmpp.TransportSession"); dojo.require("dojox.xmpp.util"); dojo.require("dojo.io.script"); dojo.require("dojo.io.iframe"); dojo.require("dojox.data.dom"); dojox.xmpp.TransportSession = function(props) { //mixin any options that we want to provide to this service if (props && dojo.isObject(props)) { dojo.mixin(this, props); if(this.useScriptSrcTransport){ this.transportIframes = []; } } }; dojox.xmpp.TransportSession._iframeOnload = function(index) { //console.log("Loaded transport iframe slot " + index, this); var doc = dojo.io.iframe.doc(dojo.byId("xmpp-transport-" + index)); //console.log("iframe document ", doc); doc.write(""); }; dojox.xmpp.TransportSession.handleBOSH = function(msg, rid) { //console.log("BOSH from iframe", msg, rid); }; dojo.extend(dojox.xmpp.TransportSession, { /* options/defaults */ rid: 0, hold: 1, polling:1000, secure: false, wait: 60, lang: 'en', submitContentType: 'text/xml; charset=utf=8', serviceUrl: '/httpbind', defaultResource: "dojoIm", domain: 'imserver.com', sendTimeout: (this.wait+20)*1000, useScriptSrcTransport:false, keepAliveTimer:null, //status state: "NotReady", transmitState: "Idle", protocolPacketQueue: [], outboundQueue: [], outboundRequests: {}, inboundQueue: [], deferredRequests: {}, matchTypeIdAttribute: {}, open: function() { this.status = "notReady"; this.rid = Math.round(Math.random() * 1000000000); this.protocolPacketQueue = []; this.outboundQueue = []; this.outboundRequests = {}; this.inboundQueue = []; this.deferredRequests = {}; this.matchTypeIdAttribute = {}; this.keepAliveTimer = setTimeout(dojo.hitch(this, "_keepAlive"), 10000); if(this.useScriptSrcTransport){ 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); if(i ==0) { 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); }, processScriptSrc: function(msg, rid) { //console.log("processScriptSrc::", rid, msg); // var msgDom = dojox.xml.DomParser.parse(msg); var msgDom = dojox.data.dom.createDocument(msg, "text/xml"); //console.log("parsed mgs", msgDom); //console.log("Queue", this.outboundQueue); if(msgDom) { this.processDocument(msgDom, rid); } else { //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); }, close: function(protocolMsg){ var rid = this.rid++; var req = { sid: this.sid, rid: rid, type: "terminate" }; var envelope = null; if (protocolMsg) { envelope = new dojox.string.Builder(dojox.xmpp.util.createElement("body", req, false)); envelope.append(protocolMsg); envelope.append(""); } else { envelope = new dojox.string.Builder(dojox.xmpp.util.createElement("body", req, false)); } // this.sendXml(envelope,rid); this.addToOutboundQueue(envelope.toString(), rid); this.state=="Terminate"; }, dispatchPacket: function(msg, protocolMatchType, matchId, matchProperty){ // summary // Main Packet dispatcher, most calls should be made with this other // than a few setup calls which use add items to the queue directly //protocolMatchType, matchId, and matchProperty are optional params //that allow a deferred to be tied to a protocol response instad of the whole //rid // //console.log("In dispatchPacket ", msg, protocolMatchType, matchId, matchProperty); if (msg){ this.protocolPacketQueue.push(msg); } var def = new dojo.Deferred(); //def.rid = req.rid; if (protocolMatchType && matchId){ def.protocolMatchType = protocolMatchType; def.matchId = matchId; def.matchProperty = matchProperty || "id"; if(def.matchProperty != "id") { this.matchTypeIdAttribute[protocolMatchType] = def.matchProperty; } } this.deferredRequests[def.protocolMatchType + "-" +def.matchId]=def; if(!this.dispatchTimer) { this.dispatchTimer = setTimeout(dojo.hitch(this, "_dispatchPacket"), 600); } return def; }, _dispatchPacket: function(){ clearTimeout(this.dispatchTimer); delete this.dispatchTimer; if (!this.sid){ console.debug("TransportSession::dispatchPacket() No SID, packet dropped.") return; } if (!this.authId){ //FIXME according to original nodes, this should wait a little while and try // again up to three times to see if we get this data. console.debug("TransportSession::dispatchPacket() No authId, packet dropped [FIXME]") return; } //if there is a pending request with the server, don't poll if (this.transmitState != "error" && (this.protocolPacketQueue.length == 0) && (this.outboundQueue.length > 0)) { return; } if (this.state=="wait" || this.isTerminated()) { return; } var req = { sid: this.sid } 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)); } this.addToOutboundQueue(envelope.toString(),req.rid); }, redispatchPacket: function(rid){ var env = this.outboundRequests[rid]; this.sendXml(env, rid); }, addToOutboundQueue: function(msg, rid){ this.outboundQueue.push({msg: msg,rid: rid}); this.outboundRequests[rid]=msg; this.sendXml(msg, rid); }, removeFromOutboundQueue: function(rid){ for(var i=0; i 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); var gap = rid-expectedId; if (gap < this.hold + 2){ this.addToInboundQueue(doc,rid); }else{ //console.log("TransportSession::processDocument() RID is outside of the expected response window"); } } return doc; }, processInboundQueue: function(){ while (this.inboundQueue.length > 0) { var item = this.inboundQueue.shift(); this.processDocument(item["doc"], item["rid"]); } }, addToInboundQueue: function(doc,rid){ for (var i=0; i