Explorar o código

MUC: Don't ping when we're not connected

Instead, wait for the `reconnection` event and then ping.
JC Brand %!s(int64=2) %!d(string=hai) anos
pai
achega
a4ee3085b7

+ 3 - 15
src/headless/plugins/muc/muc.js

@@ -1928,22 +1928,10 @@ const ChatRoomMixin = {
      * @returns {Promise<boolean>}
      */
     async isJoined () {
-        const jid = this.get('jid');
-        const ping = $iq({
-            'to': `${jid}/${this.get('nick')}`,
-            'type': 'get'
-        }).c('ping', { 'xmlns': Strophe.NS.PING });
-        try {
-            await api.sendIQ(ping);
-        } catch (e) {
-            if (e === null) {
-                log.warn(`isJoined: Timeout error while checking whether we're joined to MUC: ${jid}`);
-            } else {
-                log.warn(`isJoined: Apparently we're no longer connected to MUC: ${jid}`);
-            }
-            return false;
+        if (!api.connection.connected()) {
+            await new Promise(resolve => api.listen.once('reconnected', resolve));
         }
-        return true;
+        return api.ping(`${this.get('jid')}/${this.get('nick')}`)
     },
 
     /**

+ 25 - 20
src/headless/plugins/ping/api.js

@@ -6,39 +6,44 @@ const { Strophe, $iq, u } = converse.env;
 
 export default {
     /**
-     * Pings the service represented by the passed in JID by sending an IQ stanza.
-     * @private
+     * Pings the entity represented by the passed in JID by sending an IQ stanza to it.
+     * If we already know we're not connected, no ping is sent out and `false` is returned.
+     * If the ping is sent out to the user's bare JID and no response is received it will attempt to reconnect.
      * @method api.ping
      * @param { String } [jid] - The JID of the service to ping
      * @param { Integer } [timeout] - The amount of time in
      *  milliseconds to wait for a response. The default is 10000;
+     * @returns { Boolean } Whether the pinged entity responded with a non-error IQ stanza.
      */
     async ping (jid, timeout) {
+        if (!api.connection.connected()) {
+            log.warn("Not pinging when we know we're not connected");
+            return false;
+        }
+
         // XXX: We could first check here if the server advertised that it supports PING.
         // However, some servers don't advertise while still responding to pings
-        //
         // const feature = _converse.disco_entities[_converse.domain].features.findWhere({'var': Strophe.NS.PING});
         setLastStanzaDate(new Date());
         jid = jid || Strophe.getDomainFromJid(_converse.bare_jid);
-        if (_converse.connection) {
-            const iq = $iq({
-                    'type': 'get',
-                    'to': jid,
-                    'id': u.getUniqueId('ping')
-                }).c('ping', {'xmlns': Strophe.NS.PING});
+        const iq = $iq({
+                'type': 'get',
+                'to': jid,
+                'id': u.getUniqueId('ping')
+            }).c('ping', {'xmlns': Strophe.NS.PING});
 
-            const result = await api.sendIQ(iq, timeout || 10000, false);
-            if (result === null) {
-                log.warn(`Timeout while pinging ${jid}`);
-                if (jid === Strophe.getDomainFromJid(_converse.bare_jid)) {
-                    api.connection.reconnect();
-                }
-            } else if (u.isErrorStanza(result)) {
-                log.error(`Error while pinging ${jid}`);
-                log.error(result);
+        const result = await api.sendIQ(iq, timeout || 10000, false);
+        if (result === null) {
+            log.warn(`Timeout while pinging ${jid}`);
+            if (jid === Strophe.getDomainFromJid(_converse.bare_jid)) {
+                api.connection.reconnect();
             }
-            return true;
+            return false;
+        } else if (u.isErrorStanza(result)) {
+            log.error(`Error while pinging ${jid}`);
+            log.error(result);
+            return false;
         }
-        return false;
+        return true;
     }
 }

+ 7 - 1
src/headless/plugins/ping/tests/ping.js

@@ -21,7 +21,7 @@ describe("XMPP Ping", function () {
                 `<iq id="s2c1" to="${_converse.domain}" type="result" xmlns="jabber:client"/>`);
         }));
 
-        it("is sent out when converse.js pings a server", mock.initConverse((_converse) => {
+        it("is sent out when converse.js pings a server", mock.initConverse(['statusInitialized'], {}, (_converse) => {
             _converse.api.ping();
             const sent_stanza = _converse.connection.IQ_stanzas.pop();
             expect(Strophe.serialize(sent_stanza)).toBe(
@@ -29,5 +29,11 @@ describe("XMPP Ping", function () {
                     `<ping xmlns="urn:xmpp:ping"/>`+
                 `</iq>`);
         }));
+
+        it("is not sent out if we're not connected", mock.initConverse(async (_converse) => {
+            spyOn(_converse.connection, 'send');
+            expect(await _converse.api.ping()).toBe(false);
+            expect(_converse.connection.send.calls.count()).toBe(0);
+        }));
     });
 });