I am using Spring Framework's WebSocketClient
and WebSocketStompClient
to consume messages. The setup looks something like this:
WebSocketClient webSocketClient = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
//messageConverter is MappingJackson2MessageConverter
stompClient.setMessageConverter(messageConverter);
stompClient.setTaskScheduler(new ConcurrentTaskScheduler());
WebSocketHttpHeaders httpHeaders = new WebSocketHttpHeaders();
StompHeaders stompHeaders = new StompHeaders();
//... populate authentication headers ...
stompClient.connect(url, httpHeaders, stompHeaders, this);
The class itself implements StompSessionHandlerAdapter
.
I am then overriding the afterConnected()
method to subscribe to the required destinations and all works well.
I am also overriding handleException()
, and I was expecting that maybe when there is a connection error this would be triggered. I have a warning log inside, so I was expecting this to show something when a connection error occurs.
@Override
public void handleException(
StompSession session,
StompCommand command,
StompHeaders headers,
byte[] payload,
Throwable exception) {
logger.warn("Error on websocket session " + session.getSessionId(), exception);
}
However, when there is a connection drop I see no error. The websocket server is accessible only through the private network, so the way I am trying to simulate it is by disconnecting VPN, at which point messages just stop (no Exception is logged through handleException()
). Reconnecting VPN does not resume automatically either.
How can I detect that the websocket server is unavailable and try to reconnect periodically?
So it turns out there is another method, handleTransportError()
which gets invoked when the socket connection drops. When I override it and the websocket server becomes unavailable it is correctly getting invoked.
@Override
public void handleTransportError(StompSession session, Throwable exception) {
logger.warn("Error on websocket session " + session.getSessionId(), exception);
// todo: schedule a reconnection attempt
}
What I ended up doing is keeping a flag to know whether the client was connected or not. If this was the first disconnection it tries to re-establish the connection, otherwise it uses Spring's ThreadPoolTaskScheduler
to schedule a reconnection attempt after 5 seconds.