Reset the MUC self-presence collector on presence stanzas on join

To prevent timeouts when joining very large MUCs we now reset the
self-presence collector's timeout for every other (occupant) presence
we receive.

Fixes SMACK-859.
This commit is contained in:
Florian Schmaus 2019-03-04 23:00:45 +01:00
parent f602de8771
commit 7f0932a481
1 changed files with 16 additions and 3 deletions

View File

@ -340,8 +340,9 @@ public class MultiUserChat {
// Setup the messageListeners and presenceListeners *before* the join presence is send.
connection.addSyncStanzaListener(messageListener, fromRoomGroupchatFilter);
connection.addSyncStanzaListener(presenceListener, new AndFilter(fromRoomFilter,
StanzaTypeFilter.PRESENCE));
StanzaFilter presenceFromRoomFilter = new AndFilter(fromRoomFilter,
StanzaTypeFilter.PRESENCE);
connection.addSyncStanzaListener(presenceListener, presenceFromRoomFilter);
// @formatter:off
connection.addSyncStanzaListener(subjectListener,
new AndFilter(fromRoomFilter,
@ -370,15 +371,27 @@ public class MultiUserChat {
)
);
// @formatter:on
StanzaCollector presenceStanzaCollector = null;
Presence presence;
try {
presence = connection.createStanzaCollectorAndSend(responseFilter, joinPresence).nextResultOrThrow(conf.getTimeout());
// This stanza collector will collect the final self presence from the MUC, which also signals that we have successful entered the MUC.
StanzaCollector selfPresenceCollector = connection.createStanzaCollectorAndSend(responseFilter, joinPresence);
StanzaCollector.Configuration presenceStanzaCollectorConfguration = StanzaCollector.newConfiguration().setCollectorToReset(
selfPresenceCollector).setStanzaFilter(presenceFromRoomFilter);
// This stanza collector is used to reset the timeout of the selfPresenceCollector.
presenceStanzaCollector = connection.createStanzaCollector(presenceStanzaCollectorConfguration);
presence = selfPresenceCollector.nextResultOrThrow(conf.getTimeout());
}
catch (NotConnectedException | InterruptedException | NoResponseException | XMPPErrorException e) {
// Ensure that all callbacks are removed if there is an exception
removeConnectionCallbacks();
throw e;
}
finally {
if (presenceStanzaCollector != null) {
presenceStanzaCollector.cancel();
}
}
// This presence must be send from a full JID. We use the resourcepart of this JID as nick, since the room may
// performed roomnick rewriting