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
This commit is contained in:
parent
cb85f61fe4
commit
9e2a35f6e5
2 changed files with 31 additions and 8 deletions
|
|
@ -496,6 +496,19 @@ class XEP_0045(object):
|
|||
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 @@ class XEP_0045(object):
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -35,14 +35,15 @@ import time
|
|||
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 @@ class XEP_0198(object):
|
|||
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 @@ class XEP_0198(object):
|
|||
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 @@ class XEP_0198(object):
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue