From 39d568d396a2c54ee315878b503334efa5989ff7 Mon Sep 17 00:00:00 2001 From: damencho Date: Mon, 2 Dec 2024 11:55:24 -0600 Subject: [PATCH 1/2] feat: Enables stream resumption. --- .../org/jitsi/xmpp/mucclient/MucClient.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java b/jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java index c337e14..02ab234 100644 --- a/jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java +++ b/jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java @@ -55,8 +55,8 @@ public class MucClient static { - XMPPTCPConnection.setUseStreamManagementDefault(false); - XMPPTCPConnection.setUseStreamManagementResumptionDefault(false); + XMPPTCPConnection.setUseStreamManagementDefault(true); + XMPPTCPConnection.setUseStreamManagementResumptionDefault(true); PingManager.setDefaultPingInterval(DEFAULT_PING_INTERVAL_SECONDS); } @@ -318,13 +318,25 @@ private void initializeConnectAndJoin() public void connected(XMPPConnection xmppConnection) { mucClientManager.connected(MucClient.this); - logger.info("Connected."); + + if (xmppConnection instanceof XMPPTCPConnection) + { + XMPPTCPConnection connection = (XMPPTCPConnection) xmppConnection; + + logger.info("Connected. isSmEnabled:" + connection.isSmEnabled() + + " isSmAvailable:" + connection.isSmAvailable() + + " isSmResumptionPossible:" + connection.isSmResumptionPossible()); + } + else + { + logger.info("Connected."); + } } @Override - public void authenticated(XMPPConnection xmppConnection, boolean b) + public void authenticated(XMPPConnection xmppConnection, boolean resumed) { - logger.info("Authenticated, b=" + b); + logger.info("Authenticated, resumed=" + resumed); } @Override @@ -664,7 +676,11 @@ private Callable getConnectAndLoginCallable() try { - joinMucs(); + if (!(xmppConnection instanceof XMPPTCPConnection + && ((XMPPTCPConnection)xmppConnection).streamWasResumed())) + { + joinMucs(); + } } catch(Exception e) { From e665b33b6c0f3f61fff3b3e7f7e4a0dda1414e58 Mon Sep 17 00:00:00 2001 From: damencho Date: Tue, 3 Dec 2024 12:01:34 -0600 Subject: [PATCH 2/2] squash: This reverts to using smack reconnect. Reverts 70ac00c. --- .../org/jitsi/xmpp/mucclient/MucClient.java | 63 +++++++++++++------ 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java b/jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java index 02ab234..a6d8219 100644 --- a/jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java +++ b/jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java @@ -58,6 +58,8 @@ public class MucClient XMPPTCPConnection.setUseStreamManagementDefault(true); XMPPTCPConnection.setUseStreamManagementResumptionDefault(true); PingManager.setDefaultPingInterval(DEFAULT_PING_INTERVAL_SECONDS); + // We want to reconnect as soon as possible. + ReconnectionManager.setDefaultFixedDelay(1); } /** @@ -155,8 +157,7 @@ public class MucClient private AbstractXMPPConnection xmppConnection; /** - * The connect loop: we keep this running forever and it re-establishes the - * connection in case it's broken. + * The retry we do on initial connect. After xmpp is connected the Smack reconnect kick-ins. */ private RetryStrategy connectRetry; @@ -263,7 +264,7 @@ public MucClientConfiguration getConfig() void start() { this.executor = ExecutorUtils.newScheduledThreadPool(1, true, MucClientManager.class.getSimpleName()); - this.connectRetry = new RetryStrategy(this.executor); + this.executor.execute(() -> { try @@ -310,7 +311,7 @@ private void initializeConnectAndJoin() mucClientManager.getFeatures().forEach(sdm::addFeature); ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(xmppConnection); - reconnectionManager.disableAutomaticReconnection(); + reconnectionManager.enableAutomaticReconnection(); xmppConnection.addConnectionListener(new ConnectionListener() { @@ -337,6 +338,18 @@ public void connected(XMPPConnection xmppConnection) public void authenticated(XMPPConnection xmppConnection, boolean resumed) { logger.info("Authenticated, resumed=" + resumed); + + if (!resumed) + { + try + { + joinMucs(); + } + catch(Exception e) + { + logger.warn("Failed to join the MUCs.", e); + } + } } @Override @@ -344,6 +357,21 @@ public void connectionClosed() { mucClientManager.closed(MucClient.this); logger.info("Closed."); + + if (MucClient.this.connectRetry != null) + { + // FIXME this is a workaround for an issue that can happen + // during a short network problem (~20 secs) where requests + // on the client side timeout during it and xmpp server + // tries to close the connection by sending which + // reaches the client when the network is back. That makes + // smack disconnect the connection and never retries + // if the connection was closed, we want to continue trying + // so we will trigger the reconnection logic again + // till we are connected and will relay on smack's reconnect + MucClient.this.connectRetry.runRetryingTask( + new SimpleRetryTask(0, 1000, true, getConnectAndLoginCallable())); + } } @Override @@ -360,6 +388,7 @@ public void connectionClosedOnError(Exception e) setIQListener(mucClientManager.getIqListener()); logger.info("Dispatching a thread to connect and login."); + this.connectRetry = new RetryStrategy(this.executor); this.connectRetry.runRetryingTask(new SimpleRetryTask(0, 5000, true, getConnectAndLoginCallable())); } @@ -592,7 +621,11 @@ public String getId() */ void stop() { - this.connectRetry.cancel(); + if (this.connectRetry != null) + { + this.connectRetry.cancel(); + this.connectRetry = null; + } ReconnectionManager.getInstanceFor(xmppConnection).removeReconnectionListener(reconnectionListener); @@ -674,19 +707,13 @@ private Callable getConnectAndLoginCallable() return true; } - try - { - if (!(xmppConnection instanceof XMPPTCPConnection - && ((XMPPTCPConnection)xmppConnection).streamWasResumed())) - { - joinMucs(); - } - } - catch(Exception e) - { - logger.warn("Failed to join the MUCs.", e); - return true; - } + // The connection is successfully established, but we need to keep + // the executor alive, since it may be re-utilized by {@link #connectRetry} + // in case we ever need to restart the retry-connect-login logic. + // Essentially we need to keep the executor alive as long as we keep + // the {@link #connectRetry} alive. + + return false; } return true;