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
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
Current thread continues in XMPPBOSHConnection.connect() and set connected flag true
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.