Skip to content

Commit

Permalink
feat: Enables stream resumption. (#211)
Browse files Browse the repository at this point in the history
* feat: Enables stream resumption.

* squash: This reverts to using smack reconnect.
Reverts 70ac00c.
  • Loading branch information
damencho authored Dec 4, 2024
1 parent 37c605c commit 3afa2ac
Showing 1 changed file with 62 additions and 19 deletions.
81 changes: 62 additions & 19 deletions jicoco/src/main/java/org/jitsi/xmpp/mucclient/MucClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ public class MucClient

static
{
XMPPTCPConnection.setUseStreamManagementDefault(false);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(false);
XMPPTCPConnection.setUseStreamManagementDefault(true);
XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
PingManager.setDefaultPingInterval(DEFAULT_PING_INTERVAL_SECONDS);
// We want to reconnect as soon as possible.
ReconnectionManager.setDefaultFixedDelay(1);
}

/**
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -310,28 +311,67 @@ private void initializeConnectAndJoin()
mucClientManager.getFeatures().forEach(sdm::addFeature);

ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(xmppConnection);
reconnectionManager.disableAutomaticReconnection();
reconnectionManager.enableAutomaticReconnection();

xmppConnection.addConnectionListener(new ConnectionListener()
{
@Override
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);

if (!resumed)
{
try
{
joinMucs();
}
catch(Exception e)
{
logger.warn("Failed to join the MUCs.", e);
}
}
}

@Override
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 </stream> 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
Expand All @@ -348,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()));
}

Expand Down Expand Up @@ -580,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);

Expand Down Expand Up @@ -662,15 +707,13 @@ private Callable<Boolean> getConnectAndLoginCallable()
return true;
}

try
{
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;
Expand Down

0 comments on commit 3afa2ac

Please sign in to comment.