Commit f371b621 authored by JC Brand's avatar JC Brand

Move XMPP Ping code to a plugin.

parent 16f8b14e
...@@ -8,9 +8,10 @@ define("converse", [ ...@@ -8,9 +8,10 @@ define("converse", [
* -------------------- * --------------------
* Any of the following components may be removed if they're not needed. * Any of the following components may be removed if they're not needed.
*/ */
"converse-muc", // XEP-0045 Multi-user chat "converse-muc", // XEP-0045 Multi-user chat
"converse-otr", // Off-the-record encryption for one-on-one messages "converse-otr", // Off-the-record encryption for one-on-one messages
"converse-register", // XEP-0077 In-band registration "converse-register",// XEP-0077 In-band registration
"converse-ping", // XEP-0199 XMPP Ping
/* End: Removable components */ /* End: Removable components */
"converse-core" "converse-core"
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
## 0.11.0 (Unreleased) ## 0.11.0 (Unreleased)
- Split converse.js into different modules. - Split converse.js into different modules.
The code for the OTR, MUC and registration features are now in separate The code for the OTR, MUC, Ping and registration features are now written as
modules and these can be removed completely from the build. [jcbrand] 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 - Don't play sound notifications for OTR messages which are setting up an
encrypted session. [jcbrand] encrypted session. [jcbrand]
- Removed the `account.logout` API, instead use `user.logout`. [jcbrand] - Removed the `account.logout` API, instead use `user.logout`. [jcbrand]
......
...@@ -47,6 +47,7 @@ require.config({ ...@@ -47,6 +47,7 @@ require.config({
"converse-core": "src/converse-core", "converse-core": "src/converse-core",
"converse-muc": "src/converse-muc", "converse-muc": "src/converse-muc",
"converse-otr": "src/converse-otr", "converse-otr": "src/converse-otr",
"converse-ping": "src/converse-ping",
"converse-register": "src/converse-register", "converse-register": "src/converse-register",
"converse-dependencies": "src/deps-full", "converse-dependencies": "src/deps-full",
"converse-templates": "src/templates", "converse-templates": "src/templates",
......
...@@ -284,7 +284,6 @@ ...@@ -284,7 +284,6 @@
message_carbons: false, // Support for XEP-280 message_carbons: false, // Support for XEP-280
no_trimming: false, // Set to true for phantomjs tests (where browser apparently has no width) no_trimming: false, // Set to true for phantomjs tests (where browser apparently has no width)
password: undefined, password: undefined,
ping_interval: 180, //in seconds
play_sounds: false, play_sounds: false,
prebind: false, // XXX: Deprecated, use "authentication" instead. prebind: false, // XXX: Deprecated, use "authentication" instead.
prebind_url: null, prebind_url: null,
...@@ -741,71 +740,19 @@ ...@@ -741,71 +740,19 @@
}.bind(this), 200)); }.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 () { this.onReconnected = function () {
// We need to re-register all the event handlers on the newly // We need to re-register all the event handlers on the newly
// created connection. // created connection.
var deferred = new $.Deferred();
this.initStatus(function () { this.initStatus(function () {
this.registerPingHandler();
this.rosterview.registerRosterXHandler(); this.rosterview.registerRosterXHandler();
this.rosterview.registerPresenceHandler(); this.rosterview.registerPresenceHandler();
this.chatboxes.registerMessageHandler(); this.chatboxes.registerMessageHandler();
this.xmppstatus.sendPresence(); this.xmppstatus.sendPresence();
this.giveFeedback(__('Contacts')); this.giveFeedback(__('Contacts'));
deferred.resolve();
}.bind(this)); }.bind(this));
return deferred.promise();
}; };
this.enableCarbons = function () { this.enableCarbons = function () {
...@@ -832,10 +779,11 @@ ...@@ -832,10 +779,11 @@
this.connection.send(carbons_iq); this.connection.send(carbons_iq);
}; };
this.onConnected = function () { this.onConnected = function (callback) {
// When reconnecting, there might be some open chat boxes. We don't // 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 // know whether these boxes are of the same account or not, so we
// close them now. // close them now.
var deferred = new $.Deferred();
this.chatboxviews.closeAllChatBoxes(); this.chatboxviews.closeAllChatBoxes();
this.jid = this.connection.jid; this.jid = this.connection.jid;
this.bare_jid = Strophe.getBareJidFromJid(this.connection.jid); this.bare_jid = Strophe.getBareJidFromJid(this.connection.jid);
...@@ -845,11 +793,13 @@ ...@@ -845,11 +793,13 @@
this.features = new this.Features(); this.features = new this.Features();
this.enableCarbons(); this.enableCarbons();
this.initStatus(function () { this.initStatus(function () {
this.registerPingHandler();
this.registerIntervalHandler(); this.registerIntervalHandler();
this.chatboxes.onConnected(); this.chatboxes.onConnected();
this.giveFeedback(__('Contacts')); 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') { if (this.connection.service === 'jasmine tests') {
// XXX: Call back with the internal converse object. This // XXX: Call back with the internal converse object. This
// object should never be exposed to production systems. // object should never be exposed to production systems.
...@@ -860,8 +810,10 @@ ...@@ -860,8 +810,10 @@
this.callback(); this.callback();
} }
} }
deferred.resolve();
}.bind(this)); }.bind(this));
converse.emit('ready'); converse.emit('ready');
return deferred.promise();
}; };
this.Message = Backbone.Model.extend({ this.Message = Backbone.Model.extend({
...@@ -4630,9 +4582,6 @@ ...@@ -4630,9 +4582,6 @@
'send': function (stanza) { 'send': function (stanza) {
converse.connection.send(stanza); converse.connection.send(stanza);
}, },
'ping': function (jid) {
converse.ping(jid);
},
'plugins': { 'plugins': {
'add': function (name, plugin) { 'add': function (name, plugin) {
converse.plugins[name] = plugin; converse.plugins[name] = plugin;
......
// 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);
}
});
}
});
}));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment