diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 77a859e09..ce00484a3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -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