Strophe.addConnectionPlugin('cm', { conn: null, conn_state: null, enabled: false, element_queue: [], pingTime: 30000, pingTimeout: 30000, pingInterval: null, onEnqueueElement: null, onDequeueElement: null, init: function (connection) { this.conn = connection; this.enable(); }, statusChanged: function (status) { this.conn_state = status; }, enable: function () { this.disable(); var that = this; var conn = this.conn; // insert a tap into the builtin _queueData function var _queueData = conn._queueData; conn._queueData = function (element) { if (that._enqueueElement(element)) { _queueData.call(this, element); } else { //DF.console.log("NOT passing through queue call to Strophe Connection!"); } }; conn.xmlInput = function (xmlData) { that._requestReceived(xmlData); }; }, disable: function () { this.conn._queueData = Strophe.Connection.prototype._queueData; }, _enqueueElement: function (el) { //console.info("req sent:", el); if (!el) { return; } var conferencesFound; try { conferencesFound = el.querySelectorAll("[xmlns='jabber:x:conference']"); } catch(e) { conferencesFound = $(el).find("[xmlns='jabber:x:conference']"); } var $el = $(el); // only enqueue elements that are not used for authentication // or session establishment. // also don't buffer presence stanzas if ((Strophe.isTagEqual(el, 'iq') && el.getAttribute('id').indexOf('_auth_') != -1) || el.getAttribute('xmlns') == 'urn:ietf:params:xml:ns:xmpp-sasl' || Strophe.isTagEqual(el, 'presence') || (Strophe.isTagEqual(el, 'iq') && el.firstChild && Strophe.isTagEqual(el.firstChild, 'ping')) || (Strophe.isTagEqual(el, 'message') && conferencesFound.length > 0) ) { return true; } // only push non-empty requests if (this.element_queue.indexOf(el) == -1) { this.element_queue.push(el); if (this.onEnqueueElement) { this.onEnqueueElement(el); } } // if strophe is in the AUTHENTICATING (auth/session establishment) stage, // don't allow "regular requests" to be pushed through if (this.conn_state != Strophe.Status.CONNECTED) { return false; } return true; }, _requestReceived: function (xmlData) { // console.info("req received:", xmlData); // clear the queue var els = xmlData.childNodes; if (els && els.length > 0) { for (var i = 0; i < this.element_queue.length; i++) { for (var j = 0; j < els.length; j++) { //if(this.element_queue[i] == els[j]){ if (this.element_queue[i] && els[j] && (this.element_queue[i].getAttribute("id") == els[j].getAttribute("id"))) { // use request id comparisons instead // console.info("removing from sent queue:", this.element_queue[i]); this.element_queue.splice(i--, 1); if (this.onDequeueElement) { this.onDequeueElement(els[j]); } } } } } // console.info("sentQueue:", this.element_queue.length, this.element_queue); }, resendStanzas: function (stanzaList) { var queue = stanzaList || [], max = 20; this.conn.pause(); // facilitate bulk sending for (var i = 0; i < queue.length && i < max; i++) { this.conn.send(queue[i]); } this.conn.resume(); } /* pingServer: function(){ var self = this; var stanza = $iq({ id: "ping", type: "get", to: this.conn.domain }).c("ping", {xmlns: 'urn:xmpp:ping'}); this.conn.sendIQ(stanza, null, function(){ self.requestTimedOut(); }, this.pingTimeout); }, requestTimedOut: function(){ // stop monitoring the connection console.log("request timeout"); clearInterval(this.pingInterval); this.conn.auto_reconnect = false; this.conn.disconnect('no_pong'); }*/ });