Reconnection fixes. Fixes #712

- Remove groupviews, so that they'll get recreated upon reconnection
- Don't call `clearSession` when reconnecting. We want to reuse the
  Backbone collections.
- Emit `rosterInitialized` event and use that in converse-rosterview.js
  (instead of overriding).
- Refactor `onReconnected` to emit `rosterReadyAfterReconnection`, call
  `converse.populateRoster()` and `converse.chatboxes.onConnected()`.
- Recreate the roster view on the `rosterReadyAfterReconnection` event.
This commit is contained in:
JC Brand 2016-11-02 13:13:49 +00:00
parent 0d4993ef86
commit 38db959e11
5 changed files with 58 additions and 32 deletions

View File

@ -10,6 +10,7 @@
- Add support for XEP-0048, chat room bookmarks [jcbrand]
- New configuration setting [connection_options](https://conversejs.org/docs/html/configuration.html#connection_options) [jcbrand]
- #203 New configuration setting [muc_domain](https://conversejs.org/docs/html/configuration.html#muc_domain) [jcbrand]
- #712 Controlbox clicks stop responding after auto-reconnect [jcbrand]
## 2.0.0 (2016-09-16)
- #656 Online users count not shown initially [amanzur]

View File

@ -196,6 +196,14 @@ Triggered once roster groups have been fetched. Used by the
`converse-rosterview.js` plugin to know when it can start alphabetically
position roster groups.
rosterInitialized
~~~~~~~~~~~~~~~~~
The Backbone collections `RosterContacts` and `RosterGroups` have been created,
but not yet populated with data.
This event is useful when you want to create views for these collections.
rosterPush
~~~~~~~~~~
@ -203,6 +211,13 @@ When the roster receives a push event from server. (i.e. New entry in your buddy
``converse.listen.on('rosterPush', function (event, items) { ... });``
rosterReadyAfterReconnection
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Similar to `rosterInitialized`, but instead pertaining to reconnection. This
event indicates that the Backbone collections representing the roster and its
groups are now again available after converse.js has reconnected.
statusInitialized
~~~~~~~~~~~~~~~~~

View File

@ -121,7 +121,11 @@
this.rosterview.unregisterHandlers();
// Removes roster groups
this.rosterview.model.off().reset();
this.rosterview.undelegateEvents().remove();
this.rosterview.each(function (groupview) {
groupview.removeAll();
groupview.remove();
});
this.rosterview.remove();
}
},

View File

@ -399,7 +399,6 @@
converse.connection.reconnecting = true;
converse.connection.disconnect('re-connecting');
converse.connection.reset();
converse.clearSession();
converse._tearDown();
if (converse.authentication !== "prebind") {
converse.autoLogin();
@ -597,25 +596,6 @@
}
};
this.afterReconnected = function () {
this.registerPresenceHandler();
this.chatboxes.registerMessageHandler();
this.xmppstatus.sendPresence();
this.giveFeedback(__('Contacts'));
};
this.onReconnected = function () {
// We need to re-register all the event handlers on the newly
// created connection.
var deferred = new $.Deferred();
converse.initStatus().done(function () {
converse.afterReconnected();
deferred.resolve();
});
converse.emit('reconnected');
return deferred.promise();
};
this.enableCarbons = function () {
/* Ask the XMPP server to enable Message Carbons
* See XEP-0280 https://xmpp.org/extensions/xep-0280.html#enabling
@ -641,12 +621,16 @@
};
this.initRoster = function () {
/* Initialize the Bakcbone collections that represent the contats
* roster and the roster groups.
*/
converse.roster = new converse.RosterContacts();
converse.roster.browserStorage = new Backbone.BrowserStorage.session(
b64_sha1('converse.contacts-'+converse.bare_jid));
converse.rostergroups = new converse.RosterGroups();
converse.rostergroups.browserStorage = new Backbone.BrowserStorage.session(
b64_sha1('converse.roster.groups'+converse.bare_jid));
converse.emit('rosterInitialized');
};
this.populateRoster = function () {
@ -736,6 +720,25 @@
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();
// Give event handlers a chance to register views for the roster
// and its groups, before we start populating.
converse.emit('rosterReadyAfterReconnection');
converse.populateRoster();
converse.chatboxes.onConnected();
converse.xmppstatus.sendPresence();
converse.emit('reconnected');
converse.giveFeedback(__('Contacts'));
};
this.RosterContact = Backbone.Model.extend({
initialize: function (attributes, options) {

View File

@ -52,17 +52,6 @@
this.__super__.afterReconnected.apply(this, arguments);
},
initRoster: function () {
/* Create an instance of RosterView once the RosterGroups
* collection has been created (in converse-core.js)
*/
this.__super__.initRoster.apply(this, arguments);
converse.rosterview = new converse.RosterView({
'model': converse.rostergroups
});
converse.rosterview.render();
},
RosterGroups: {
comparator: function () {
// RosterGroupsComparator only gets set later (once i18n is
@ -900,6 +889,20 @@
}
}
});
/* -------- Event Handlers ----------- */
var initRoster = function () {
/* Create an instance of RosterView once the RosterGroups
* collection has been created (in converse-core.js)
*/
converse.rosterview = new converse.RosterView({
'model': converse.rostergroups
});
converse.rosterview.render();
};
converse.on('rosterInitialized', initRoster);
converse.on('rosterReadyAfterReconnection', initRoster);
}
});
}));