Reconnection fixes.

- Reconnection failed if original connection was never established
- When the `credentials_url` is specified, keep on trying to reconnect.
This commit is contained in:
JC Brand 2016-11-23 11:53:06 +00:00
parent e90632d6fd
commit bfde4d3e4c
2 changed files with 56 additions and 60 deletions

View File

@ -10,6 +10,11 @@
collection has its `browserStorage` configured.
Causes `Error: A "url" property or function must be specified`. [jcbrand]
- Don't open the controlbox on contact requests. [jcbrand]
- Bugfix: Reconnection fails when original connection was never established. [jcbrand]
- If a `credentials_url` is provided, then keep on attempting to reconnect when connection is down. [jcbrand]
- Remove (undocumented) `callback` config parameter for `converse.initialize`.
Instead, `converse.initialize` returns a promise which will resolve once
initialization is complete. [jcbrand]
## 2.0.1 (2016-11-07)
- #203 New configuration setting [muc_domain](https://conversejs.org/docs/html/configuration.html#muc_domain) [jcbrand]

View File

@ -396,11 +396,7 @@
converse.connection.disconnect('re-connecting');
converse.connection.reset();
converse._tearDown();
if (converse.authentication !== "prebind") {
converse.autoLogin();
} else if (converse.prebind_url) {
converse.startNewBOSHSession();
}
converse.logIn(null, true);
}, 1000);
this.onDisconnected = function (condition) {
@ -440,7 +436,7 @@
delete converse.disconnection_cause;
if (converse.connection.reconnecting) {
converse.log(status === Strophe.Status.CONNECTED ? 'Reconnected' : 'Reattached');
converse.onReconnected();
converse.onConnected(true);
} else {
converse.log(status === Strophe.Status.CONNECTED ? 'Connected' : 'Attached');
if (converse.connection.restored) {
@ -666,19 +662,33 @@
}
};
this.onStatusInitialized = function () {
converse.registerIntervalHandler();
converse.initRoster();
this.onStatusInitialized = function (reconnecting) {
/* Continue with session establishment (e.g. fetching chat boxes,
* populating the roster etc.) necessary once the connection has
* been established.
*/
if (reconnecting) {
// No need to recreate the roster, otherwise we lose our
// cached data. However we still emit an event, to give
// event handlers a chance to register views for the
// roster and its groups, before we start populating.
converse.emit('rosterReadyAfterReconnection');
} else {
converse.registerIntervalHandler();
converse.initRoster();
}
// First set up chat boxes, before populating the roster, so that
// the controlbox is properly set up and ready for the rosterview.
converse.chatboxes.onConnected();
converse.populateRoster();
converse.registerPresenceHandler();
converse.giveFeedback(__('Contacts'));
if (typeof converse.callback === 'function') {
// XXX: Deprecate in favor of init_deferred
converse.callback();
if (reconnecting) {
converse.xmppstatus.sendPresence();
} else {
init_deferred.resolve();
converse.emit('initialized');
}
init_deferred.resolve();
converse.emit('initialized');
};
this.setUserJid = function () {
@ -688,52 +698,33 @@
converse.domain = Strophe.getDomainFromJid(converse.connection.jid);
};
this.onConnected = function (callback) {
this.onConnected = function (reconnecting) {
/* Called as soon as a new connection has been established, either
* by logging in or by attaching to an existing BOSH session.
*/
// XXX: ran into an issue where a returned PubSub BOSH response was
// not received by the browser. The solution was to flush the
// connection early on. I don't know what the underlying cause of
// this issue is, and whether it's a Strophe.js or Prosody bug.
// My suspicion is that Prosody replies to an invalid/expired
// Request, which is why the browser then doesn't receive it.
// In any case, flushing here (sending out a new BOSH request)
// solves the problem.
// Solves problem of returned PubSub BOSH response not received
// by browser.
converse.connection.flush();
// 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.
converse.chatboxviews.closeAllChatBoxes();
converse.setUserJid();
converse.features = new converse.Features();
converse.enableCarbons();
converse.initStatus().done(converse.onStatusInitialized);
converse.emit('connected');
converse.emit('ready'); // BBB: Will be removed.
};
this.onReconnected = function () {
/* Called when converse has succesfully reconnected to the XMPP
* server after the session was dropped.
* Similar to the `onConnected` method, but skips a few unnecessary
* steps.
*/
converse.setUserJid();
converse.registerPresenceHandler();
converse.chatboxes.registerMessageHandler();
if (_.isUndefined(converse.roster)) {
converse.initRoster();
converse.enableCarbons();
// If there's no xmppstatus obj, then we were never connected to
// begin with, so we set reconnecting to false.
reconnecting = _.isUndefined(converse.xmppstatus) ? false : reconnecting;
if (reconnecting) {
converse.onStatusInitialized(true);
converse.emit('reconnected');
} else {
// Give event handlers a chance to register views for the
// roster and its groups, before we start populating.
converse.emit('rosterReadyAfterReconnection');
// 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.
converse.chatboxviews.closeAllChatBoxes();
converse.features = new converse.Features();
converse.initStatus().done(_.partial(converse.onStatusInitialized, false));
converse.emit('connected');
}
converse.chatboxes.onConnected();
converse.populateRoster();
converse.xmppstatus.sendPresence();
converse.emit('reconnected');
converse.giveFeedback(__('Contacts'));
};
this.RosterContact = Backbone.Model.extend({
@ -1777,10 +1768,10 @@
});
};
this.attemptPreboundSession = function (tokens) {
this.attemptPreboundSession = function (reconnecting) {
/* Handle session resumption or initialization when prebind is being used.
*/
if (this.keepalive) {
if (!reconnecting && this.keepalive) {
if (!this.jid) {
throw new Error("attemptPreboundSession: when using 'keepalive' with 'prebind, "+
"you must supply the JID of the current user.");
@ -1794,7 +1785,7 @@
}
// No keepalive, or session resumption has failed.
if (this.jid && this.sid && this.rid) {
if (!reconnecting && this.jid && this.sid && this.rid) {
return this.connection.attach(this.jid, this.sid, this.rid, this.onConnectStatusChanged);
} else if (this.prebind_url) {
return this.startNewBOSHSession();
@ -1841,14 +1832,14 @@
}
};
this.attemptNonPreboundSession = function (credentials) {
this.attemptNonPreboundSession = function (credentials, reconnecting) {
/* Handle session resumption or initialization when prebind is not being used.
*
* Two potential options exist and are handled in this method:
* 1. keepalive
* 2. auto_login
*/
if (this.keepalive) {
if (this.keepalive && !reconnecting) {
try {
return this.connection.restore(this.jid, this.onConnectStatusChanged);
} catch (e) {
@ -1877,13 +1868,13 @@
}
};
this.logIn = function (credentials) {
this.logIn = function (credentials, reconnecting) {
// We now try to resume or automatically set up a new session.
// Otherwise the user will be shown a login form.
if (this.authentication === converse.PREBIND) {
this.attemptPreboundSession();
this.attemptPreboundSession(reconnecting);
} else {
this.attemptNonPreboundSession(credentials);
this.attemptNonPreboundSession(credentials, reconnecting);
}
};