Bug 1151462 - Send XMPP pings if there has been no outgoing activity to avoid Openfire disconnects. r=clokep, a=rkent
authoraleth <aleth@instantbird.org>
Thu, 23 Apr 2015 23:44:20 +0200
changeset 25890 c45ebbab90cbd5b0e18d80c8ef5d77e04e02cc24
parent 25889 31d8992f40e9db7d4806be109d662a532d79d7dc
child 25891 4affdec9414abe8b3a26b9e7f90e9fa294f71552
push id1850
push userclokep@gmail.com
push dateWed, 08 Mar 2017 19:29:12 +0000
treeherdercomm-esr52@028df196b2d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersclokep, rkent
bugs1151462
Bug 1151462 - Send XMPP pings if there has been no outgoing activity to avoid Openfire disconnects. r=clokep, a=rkent
chat/protocols/xmpp/xmpp-session.jsm
--- a/chat/protocols/xmpp/xmpp-session.jsm
+++ b/chat/protocols/xmpp/xmpp-session.jsm
@@ -63,16 +63,35 @@ XMPPSession.prototype = {
   __proto__: Socket,
   connectTimeout: 60,
   readWriteTimeout: 300,
   sendPing: function() {
     this.sendStanza(Stanza.iq("get", null, null,
                               Stanza.node("ping", Stanza.NS.ping)),
                     this.cancelDisconnectTimer, this);
   },
+  _lastReceiveTime: 0,
+  _lastSendTime: 0,
+  checkPingTimer(aJustSentSomething = false) {
+    // Don't start a ping timer if we're not fully connected yet.
+    if (this.onXmppStanza != this.stanzaListeners.accountListening)
+      return;
+    let now = Date.now();
+    if (aJustSentSomething)
+      this._lastSendTime = now;
+    else
+      this._lastReceiveTime = now;
+    // We only cancel the ping timer if we've both received and sent
+    // something in the last two minutes. This is because Openfire
+    // servers will disconnect us if we don't send anything for a
+    // couple of minutes.
+    if (Math.min(this._lastSendTime, this._lastReceiveTime) >
+        now - this.kTimeBeforePing)
+      this.resetPingTimer();
+  },
 
   get DEBUG() this._account.DEBUG,
   get LOG() this._account.LOG,
   get WARN() this._account.WARN,
   get ERROR() this._account.ERROR,
 
   _security: null,
   _encrypted: false,
@@ -107,16 +126,17 @@ XMPPSession.prototype = {
    * undefined return value is treated as true.
    */
   sendStanza: function(aStanza, aCallback, aThis) {
     if (!aStanza.attributes.hasOwnProperty("id"))
       aStanza.attributes["id"] = this._account.generateId();
     if (aCallback)
       this._handlers.set(aStanza.attributes.id, aCallback.bind(aThis));
     this.send(aStanza.getXML());
+    this.checkPingTimer(true);
     return aStanza.attributes.id;
   },
 
   /* This method handles callbacks for specific ids. */
   execHandler: function(aId, aStanza) {
     let handler = this._handlers.get(aId);
     if (!handler)
       return false;
@@ -169,18 +189,17 @@ XMPPSession.prototype = {
     else
       this.onXmppStanza = this.stanzaListeners.initStream;
     this._account.reportConnecting(_("connection.initializingStream"));
     this.startStream();
   },
 
   /* When incoming data is available to be parsed */
   onDataReceived: function(aData) {
-    if (this.onXmppStanza == this.stanzaListeners.accountListening)
-      this.resetPingTimer();
+    this.checkPingTimer();
     let istream = Cc["@mozilla.org/io/string-input-stream;1"]
                     .createInstance(Ci.nsIStringInputStream);
     istream.setData(aData, aData.length);
     this._lastReceivedData = aData;
     try {
       this._parser.onDataAvailable(istream, 0, aData.length);
     } catch(e) {
       Cu.reportError(e);