In my application I'm using STOMP over WebSocket for communication between microservices, I'm trying to implement session disconnect event listener to reestablish connection between microservices. According to Spring's documentation SessionDisconnectEvent
should be published when a STOMP session ends. That's how I've tried to catch the event:
@Component
public class SessionDisconnectListener implements ApplicationListener<SessionDisconnectEvent> {
@EventListener
@Override
public void onApplicationEvent(SessionDisconnectEvent applicationEvent) {
System.out.println("SESSION " + applicationEvent.getSessionId() + " DISCONNECTED");
}
}
I can see in my application that the session status changes from connected to disconnected but unfortunately this method is newer invoked. How can I properly catch session disconnect event?
You can implement a disconnect handler in your StompSessionHandlerAdapter
. In the adapter you need to implement handleTransportError(session, exception)
, all connection failure events will go through this method and you should implement your disconnect handler there. You can determine whether connection has been lost based on the passed exception or by checking the connection status of your session, I personally prefer latter.
AtomicBoolean reconnecting = new AtomicBoolean();
@public void handleTransportError(StompSession session, Throwable exception) {
If (!session.isConnected()) {
If (reconnecting.compareAndSet(false, true)) { //Ensures that only one thread tries to reconnect
try {
reestablishConnection();
} finally {
reconnecting.set(false);
}
}
} else {} //Log exception here
}
private void reestablishConnection() {
boolean disconnected = true;
while (disconnected) {
try {
TimeUnit.SECONDS.sleep(sleepTime); //Specify here for how long do you want to wait between each reconnect attempt
} catch (Exception e) {} //If an exception happens here then the service is most likely being shut down
try {
stompClient.connect(url, this).get();
disconnected = false;
} catch (Exception e) {} //Add logging etc. here
}
}