powered by Jive Software

Bug identified - Reconnection Manager not reconnectting with BOSHConnection


#1

I checked many issues related to ReconnectionManager like this , this and this all complaining about reconnection manager not able to reconnect and no reply/fix yet. I think I have found the bug.

My Smack library version is - 4.2.4
SMPP server - ejabberd 18.04

Basically reconnection manager tries to reconnect only when connection is not already established (connected flag is false in AbstractXMPPConnection). The flow goes like this

  1. AbstractXMPPConnection.connect()

  2. Put exchange msg in queue
    2.1 RequestProcessor picks up this message in new thread
    2.2 As connection fails (due to e.g. network error ), raise BOSHClientConnEvent and notify ConnectionListner with connectionClosedOnError call.
    2.3 ReconnectionManager notified about connection failure with above event.
    2.4 ReconnectionManager check if isConnected= false and tries reconnecting

  3. Current thread continues in XMPPBOSHConnection.connect() and set connected flag true

  4. Current Thread send connection event to listen with ConnectionListner.connected()

In above flow when 2.4 execute first, it tries to reconnect first time but then once step 4 is finished in main thread it marks connection ad connected and then reconnection manager never tries and we don’t have any option then to restart client.

Below is main stracktrace that I caught.
While connection fails, one thread send connectionCloseOnError notificaion

XMPPBOSHConnection.shutdown() line: 265	
XMPPBOSHConnection.notifyConnectionError(Exception) line: 407	
XMPPBOSHConnection$BOSHConnectionListener.connectionEvent(BOSHClientConnEvent) line: 454	
BOSHClient.fireConnectionClosedOnError(Throwable) line: 1675	
BOSHClient.dispose(Throwable) line: 705	
BOSHClient.processExchange(int, HTTPExchange) line: 1129	
BOSHClient.processMessages(int) line: 990	
BOSHClient.access$300(BOSHClient, int) line: 100	
BOSHClient$RequestProcessor.run() line: 1719	
Thread.run() line: 745	

While another thread continues after send call and mark connected=true

BOSHClient.send(ComposableBody) line: 506	
XMPPBOSHConnection.connectInternal() line: 177	
XMPPBOSHConnection(AbstractXMPPConnection).connect() line: 383	
ReconnectionManager$2.run() line: 289	
Thread.run() line: 745	

So ReconnectionManager.isReconnectionPossible() return false is connection.isConnected() calls return true even client was not connected to server.

Simple way to reproduce is to start client without starting server. Even when ReconnectionManager is set to call at Fixed delay it will at max calls only once.

To resolve issue, I think connect() method should wait for event from RequestProcessor or some other way it should find if connection is already established and then only return.


#2

Smack’s BOSH code is old and not actively maintained. If you can’t fix it yourself (patches welcome) have a look at https://github.com/igniterealtime/Smack#professional-services


#3

Hi, I’m not sure why you are saying only “BOSHConnection” should be affected, because I’m using XMPPTCPConnection and I have the same issue.

I’m also not sure how you are supposed to “activate” ReconnectionManager, I don’t think it’s documented anywhere and the forum posts are giving contradictory informations (like : “it’s auto activated, u dont need to activate it”, or people using explicitly “getInstanceFor(…)”).

Looking at the code, I’d say calling “ReconnectionManager.setEnabledPerDefault(true);” before creating any connection should be enough to activate ReconnectionManager for all future connections, am I right ?