Răsfoiți Sursa

Move XMPP Ping code to a plugin.

JC Brand 9 ani în urmă
părinte
comite
f371b62157
5 a modificat fișierele cu 156 adăugiri și 67 ștergeri
  1. 4 3
      converse.js
  2. 2 2
      docs/CHANGES.md
  3. 1 0
      main.js
  4. 11 62
      src/converse-core.js
  5. 138 0
      src/converse-ping.js

+ 4 - 3
converse.js

@@ -8,9 +8,10 @@ define("converse", [
      * --------------------
      * Any of the following components may be removed if they're not needed.
      */
-    "converse-muc", // XEP-0045 Multi-user chat
-    "converse-otr", // Off-the-record encryption for one-on-one messages
-    "converse-register", // XEP-0077 In-band registration
+    "converse-muc",     // XEP-0045 Multi-user chat
+    "converse-otr",     // Off-the-record encryption for one-on-one messages
+    "converse-register",// XEP-0077 In-band registration
+    "converse-ping",    // XEP-0199 XMPP Ping
     /* End: Removable components */
 
     "converse-core"

+ 2 - 2
docs/CHANGES.md

@@ -3,8 +3,8 @@
 ## 0.11.0 (Unreleased)
 
 - Split converse.js into different modules.
-  The code for the OTR, MUC and registration features are now in separate
-  modules and these can be removed completely from the build. [jcbrand]
+  The code for the OTR, MUC, Ping and registration features are now written as
+  plugins in separate modules and they can be completely removed from the build. [jcbrand]
 - Don't play sound notifications for OTR messages which are setting up an
   encrypted session. [jcbrand]
 - Removed the `account.logout` API, instead use `user.logout`. [jcbrand]

+ 1 - 0
main.js

@@ -47,6 +47,7 @@ require.config({
         "converse-core":            "src/converse-core",
         "converse-muc":             "src/converse-muc",
         "converse-otr":             "src/converse-otr",
+        "converse-ping":            "src/converse-ping",
         "converse-register":        "src/converse-register",
         "converse-dependencies":    "src/deps-full",
         "converse-templates":       "src/templates",

+ 11 - 62
src/converse-core.js

@@ -284,7 +284,6 @@
             message_carbons: false, // Support for XEP-280
             no_trimming: false, // Set to true for phantomjs tests (where browser apparently has no width)
             password: undefined,
-            ping_interval: 180, //in seconds
             play_sounds: false,
             prebind: false, // XXX: Deprecated, use "authentication" instead.
             prebind_url: null,
@@ -741,71 +740,19 @@
             }.bind(this), 200));
         };
 
-        this.ping = function (jid, success, error, timeout) {
-            // XXX: We could first check here if the server advertised that it supports PING.
-            // However, some servers don't advertise while still keeping the
-            // connection option due to pings.
-            //
-            // var feature = converse.features.findWhere({'var': Strophe.NS.PING});
-            converse.lastStanzaDate = new Date();
-            if (typeof jid === 'undefined' || jid === null) {
-                jid = Strophe.getDomainFromJid(converse.bare_jid);
-            }
-            if (typeof timeout === 'undefined' ) { timeout = null; }
-            if (typeof success === 'undefined' ) { success = null; }
-            if (typeof error === 'undefined' ) { error = null; }
-            if (converse.connection) {
-                converse.connection.ping.ping(jid, success, error, timeout);
-                return true;
-            }
-            return false;
-        };
-		
-        this.pong = function (ping) {
-            converse.lastStanzaDate = new Date();
-            converse.connection.ping.pong(ping);
-            return true;
-        };
-
-        this.registerPongHandler = function () {
-            converse.connection.disco.addFeature(Strophe.NS.PING);
-            converse.connection.ping.addPingHandler(this.pong);
-        };
-
-        this.registerPingHandler = function () {
-            this.registerPongHandler();
-            if (this.ping_interval > 0) {
-                this.connection.addHandler(function () {
-                    /* Handler on each stanza, saves the received date
-                     * in order to ping only when needed.
-                     */
-                    this.lastStanzaDate = new Date();
-                    return true;
-                }.bind(converse));
-                this.connection.addTimedHandler(1000, function () {
-                    var now = new Date();
-                    if (!this.lastStanzaDate) {
-                        this.lastStanzaDate = now;
-                    }
-                    if ((now - this.lastStanzaDate)/1000 > this.ping_interval) {
-                        return this.ping();
-                    }
-                    return true;
-                }.bind(converse));
-            }
-        };
-
         this.onReconnected = function () {
             // We need to re-register all the event handlers on the newly
             // created connection.
+            var deferred = new $.Deferred();
             this.initStatus(function () {
-                this.registerPingHandler();
                 this.rosterview.registerRosterXHandler();
                 this.rosterview.registerPresenceHandler();
                 this.chatboxes.registerMessageHandler();
                 this.xmppstatus.sendPresence();
                 this.giveFeedback(__('Contacts'));
+                deferred.resolve();
             }.bind(this));
+            return deferred.promise();
         };
 
         this.enableCarbons = function () {
@@ -832,10 +779,11 @@
             this.connection.send(carbons_iq);
         };
 
-        this.onConnected = function () {
+        this.onConnected = function (callback) {
             // When reconnecting, there might be some open chat boxes. We don't
             // know whether these boxes are of the same account or not, so we
             // close them now.
+            var deferred = new $.Deferred();
             this.chatboxviews.closeAllChatBoxes();
             this.jid = this.connection.jid;
             this.bare_jid = Strophe.getBareJidFromJid(this.connection.jid);
@@ -845,11 +793,13 @@
             this.features = new this.Features();
             this.enableCarbons();
             this.initStatus(function () {
-                this.registerPingHandler();
                 this.registerIntervalHandler();				
                 this.chatboxes.onConnected();
                 this.giveFeedback(__('Contacts'));
-                if (this.callback) {
+                if (typeof this.callback === 'function') {
+                    // A callback method may be passed in via the
+                    // converse.initialize method.
+                    // XXX: Can we use $.Deferred instead of this callback?
                     if (this.connection.service === 'jasmine tests') {
                         // XXX: Call back with the internal converse object. This
                         // object should never be exposed to production systems.
@@ -860,8 +810,10 @@
                         this.callback();
                     }
                 }
+                deferred.resolve();
             }.bind(this));
             converse.emit('ready');
+            return deferred.promise();
         };
 
         this.Message = Backbone.Model.extend({
@@ -4630,9 +4582,6 @@
         'send': function (stanza) {
             converse.connection.send(stanza);
         },
-        'ping': function (jid) {
-            converse.ping(jid);
-        },
         'plugins': {
             'add': function (name, plugin) {
                 converse.plugins[name] = plugin;

+ 138 - 0
src/converse-ping.js

@@ -0,0 +1,138 @@
+// Converse.js (A browser based XMPP chat client)
+// http://conversejs.org
+//
+// Copyright (c) 2012-2016, Jan-Carel Brand <jc@opkode.com>
+// Licensed under the Mozilla Public License (MPLv2)
+//
+/*global converse, utils, define */
+
+/* This is a Converse.js plugin which add support for application-level pings
+ * as specified in XEP-0199 XMPP Ping.
+ */
+(function (root, factory) {
+    if (typeof define === 'function' && define.amd) {
+        // AMD module loading
+        define("converse-ping", ["converse-core", "utils"], factory);
+    } else {
+        // When not using a module loader
+        // -------------------------------
+        // In this case, the dependencies need to be available already as
+        // global variables, and should be loaded separately via *script* tags.
+        // See the file **non_amd.html** for an example of this usecase.
+        factory(converse, utils);
+    }
+}(this, function (converse_api, utils) {
+    "use strict";
+    // Strophe methods for building stanzas
+    var Strophe = converse_api.env.Strophe;
+    // Other necessary globals
+    var _ = converse_api.env._;
+
+    // Translation machinery
+    // ---------------------
+    // Just a placeholder for now, we need to bind the utils.__ method to the
+    // inner converse object, which we can't here, so we do it in the
+    // initialize method.
+    var __ =  function () {};
+
+    converse_api.plugins.add('ping', {
+
+        overrides: {
+            // Overrides mentioned here will be picked up by converse.js's
+            // plugin architecture they will replace existing methods on the
+            // relevant objects or classes.
+            //
+            // New functions which don't exist yet can also be added.
+
+            onConnected: function () {
+                var converse = this._super.converse;
+                this._super.onConnected().done(converse.registerPingHandler);
+            },
+            onReconnected: function () {
+                // We need to re-register the ping event handler on the newly
+                // created connection.
+                var converse = this._super.converse;
+                this._super.onReconnected().done(converse.registerPingHandler);
+            }
+        },
+
+        initialize: function () {
+            /* The initialize function gets called as soon as the plugin is
+             * loaded by converse.js's plugin machinery.
+             */
+            var converse = this.converse;
+            // For translations
+            __ = utils.__.bind(converse);
+            // Configuration values for this plugin
+            var settings = {
+                ping_interval: 180 //in seconds
+            };
+            _.extend(converse, settings);
+            _.extend(converse, _.pick(converse.user_settings, Object.keys(settings)));
+
+            converse.ping = function (jid, success, error, timeout) {
+                // XXX: We could first check here if the server advertised that
+                // it supports PING.
+                // However, some servers don't advertise while still keeping the
+                // connection option due to pings.
+                //
+                // var feature = converse.features.findWhere({'var': Strophe.NS.PING});
+                converse.lastStanzaDate = new Date();
+                if (typeof jid === 'undefined' || jid === null) {
+                    jid = Strophe.getDomainFromJid(converse.bare_jid);
+                }
+                if (typeof timeout === 'undefined' ) { timeout = null; }
+                if (typeof success === 'undefined' ) { success = null; }
+                if (typeof error === 'undefined' ) { error = null; }
+                if (converse.connection) {
+                    converse.connection.ping.ping(jid, success, error, timeout);
+                    return true;
+                }
+                return false;
+            };
+
+            converse.pong = function (ping) {
+                converse.lastStanzaDate = new Date();
+                converse.connection.ping.pong(ping);
+                return true;
+            };
+
+            converse.registerPongHandler = function () {
+                converse.connection.disco.addFeature(Strophe.NS.PING);
+                converse.connection.ping.addPingHandler(this.pong);
+            };
+
+            converse.registerPingHandler = function () {
+                converse.registerPongHandler();
+                if (converse.ping_interval > 0) {
+                    converse.connection.addHandler(function () {
+                        /* Handler on each stanza, saves the received date
+                         * in order to ping only when needed.
+                         */
+                        converse.lastStanzaDate = new Date();
+                        return true;
+                    });
+                    converse.connection.addTimedHandler(1000, function () {
+                        var now = new Date();
+                        if (!converse.lastStanzaDate) {
+                            converse.lastStanzaDate = now;
+                        }
+                        if ((now - converse.lastStanzaDate)/1000 > this.ping_interval) {
+                            return converse.ping();
+                        }
+                        return true;
+                    });
+                }
+            };
+
+            _.extend(converse_api, {
+                /* We extend the default converse.js API to add a method specific
+                 * to this plugin.
+                 */
+                'ping': function (jid) {
+                    converse.ping(jid);
+                }
+            });
+        }
+    });
+}));