Mercurial > libervia-backend
changeset 3008:c8c68a3b0a79
plugins XEP-0045, XEP-0198: rejoin MUC rooms while a hot reconnection is done:
when resuming is not possible with stream management, a hot reconnection is done
(reconnecting without restarting every plugin). This was causing trouble for joined MUC
rooms, which were not accessible anymore (because they were not re-joined).
This patch fixes it by clearing rooms first (to avoid considering the room joined and
broadcasting the initial presence to them), then re-joining them.
fix 322
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 16 Jul 2019 21:59:30 +0200 |
parents | 420897488080 |
children | bba1c51bf2c6 |
files | sat/plugins/plugin_xep_0045.py sat/plugins/plugin_xep_0198.py |
diffstat | 2 files changed, 31 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0045.py Mon Jul 15 22:36:28 2019 +0200 +++ b/sat/plugins/plugin_xep_0045.py Tue Jul 16 21:59:30 2019 +0200 @@ -496,6 +496,19 @@ errbackArgs=(client, room_jid, nick, password)) return d + def popRooms(self, client): + """Remove rooms and return data needed to re-join them + + This methods is to be called before a hot reconnection + @return (list[(jid.JID, unicode)]): arguments needed to re-join the rooms + This list can be used directly (unpacked) with self.join + """ + args_list = [] + for room in client._muc_client.joined_rooms.values(): + client._muc_client._removeRoom(room.roomJID) + args_list.append((client, room.roomJID, room.nick)) + return args_list + def _nick(self, room_jid_s, nick, profile_key=C.PROF_KEY_NONE): client = self.host.getClient(profile_key) return self.nick(client, jid.JID(room_jid_s), nick) @@ -785,7 +798,8 @@ whois_msg.append(_("Show: %s") % user.show) def presenceTrigger(self, presence_elt, client): - # XXX: shouldn't it be done by the server ?!! + # FIXME: should we add a privacy parameters in settings to activate before + # broadcasting the presence to all MUC rooms ? muc_client = client._muc_client for room_jid, room in muc_client.joined_rooms.iteritems(): elt = xml_tools.elementCopy(presence_elt)
--- a/sat/plugins/plugin_xep_0198.py Mon Jul 15 22:36:28 2019 +0200 +++ b/sat/plugins/plugin_xep_0198.py Tue Jul 16 21:59:30 2019 +0200 @@ -35,14 +35,15 @@ log = getLogger(__name__) PLUGIN_INFO = { - C.PI_NAME: "Stream Management", - C.PI_IMPORT_NAME: "XEP-0198", - C.PI_TYPE: "XEP", + C.PI_NAME: u"Stream Management", + C.PI_IMPORT_NAME: u"XEP-0198", + C.PI_TYPE: u"XEP", C.PI_MODES: C.PLUG_MODE_BOTH, - C.PI_PROTOCOLS: ["XEP-0198"], + C.PI_PROTOCOLS: [u"XEP-0198"], C.PI_DEPENDENCIES: [], - C.PI_MAIN: "XEP_0198", - C.PI_HANDLER: "yes", + C.PI_RECOMMENDATIONS: [u"XEP-0045"], + C.PI_MAIN: u"XEP_0198", + C.PI_HANDLER: u"yes", C.PI_DESCRIPTION: _(u"""Implementation of Stream Management"""), } @@ -394,6 +395,10 @@ client.conn_deferred = defer.Deferred() else: log.error(u"conn_deferred should be called at this point") + plg_0045 = self.host.plugins.get(u'XEP-0045') + if plg_0045 is not None: + # we have to remove joined rooms + muc_join_args = plg_0045.popRooms(client) # we need to recreate roster client.handlers.remove(client.roster) client.roster = client.roster.__class__(self.host) @@ -412,6 +417,10 @@ d.addCallback(lambda __: client.roster.got_roster) # initial presence must be sent manually d.addCallback(lambda __: client.presence.available()) + if plg_0045 is not None: + muc_d_list = defer.DeferredList( + [plg_0045.join(*args) for args in muc_join_args]) + d.addCallback(lambda __: muc_d_list) def onReceive(self, element, client): if not client.is_component: @@ -437,7 +446,7 @@ session.ack_requested = False if self._ack_timeout: if session.req_timer is None: - log.error("reg_timer should be set") + log.error("req_timer should be set") else: session.req_timer.cancel() session.req_timer = None