4

I want to be able to detect when the user has lost connection with the server (closed tab, lost internet connection, etc.) I am using stompjs over Sockjs on my client and spring mvc websockets on my server.

How can i detect when the client has lost connection. Here is how i configure my websocket message brocket:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {
    @Autowired
    private TaskScheduler scheduler;

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic").setHeartbeatValue(new long[]{10000, 10000}).setTaskScheduler(scheduler);
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/web").setAllowedOrigins("*").withSockJS();
    }
}

And here is my controller class that actualy handles the incoming socket messages:

@RestController
@CrossOrigin
public class WebMessagingController {

    @MessageMapping("/chat/message")
    public void newUserMessage(String json) throws IOException {
        messagesProcessor.processUserMessage(json);
    }
}

I know that if i would have used class that extends from TextWebSocketHandler i would have bean able to override methods that are being called on connection and disconnection of the client, but i don`t think this is going to work with sock-js client. Thank you.

2 Answers2

10

In addition to Artem's response, you can use @EventListener annotation in any spring bean:

@EventListener
public void onDisconnectEvent(SessionDisconnectEvent event) {
    LOGGER.debug("Client with username {} disconnected", event.getUser());
}
gmode
  • 3,601
  • 4
  • 31
  • 39
  • You are a hero too! – ata Dec 11 '20 at 05:11
  • 1
    How get url from which user got disconnected? Stomp header destination is always null – Feroz Siddiqui Aug 21 '22 at 09:21
  • @FerozSiddiqui you won't get Destination in the Disconnect event. You can store the session at time of SUBSCRIBE along with session ID, and on disconnect, you find by session ID. Also, you receive destination in the SUBSCRIBE event, so you can store that too and later get the url on Disconnect from your DB. – Gladiator9120 Feb 08 '23 at 12:41
4

The StompSubProtocolHandler implements afterSessionEnded() which is called from the WebSocketHandler.afterConnectionClosed(). And the former emits an event like this:

/**
 * Event raised when the session of a WebSocket client using a Simple Messaging
 * Protocol (e.g. STOMP) as the WebSocket sub-protocol is closed.
 *
 * <p>Note that this event may be raised more than once for a single session and
 * therefore event consumers should be idempotent and ignore a duplicate event.
 *
 * @author Rossen Stoyanchev
 * @since 4.0.3
 */
@SuppressWarnings("serial")
public class SessionDisconnectEvent extends AbstractSubProtocolEvent {

So, what you need is an ApplicationListener for this SessionDisconnectEvent and all the information is there in the event.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Hmm, anyone know how to do this before Spring 5.0? – David Bradley Feb 03 '20 at 19:40
  • 1
    Bot sure what is your question about. The API is really there from some `4.x` version. So, you do exactly there same. If something doesn't work, it would be better to raise a new SO thread. Somehow context of this is slightly different... – Artem Bilan Feb 03 '20 at 19:47
  • I'm not seeing it in 4.2.8 but maybe I missed a dependency or something. – David Bradley May 11 '20 at 12:51
  • 1
    You're doing something wrong. This is indeed `4.2.8` version: https://github.com/spring-projects/spring-framework/blob/v4.2.8.RELEASE/spring-websocket/src/main/java/org/springframework/web/socket/messaging/SessionDisconnectEvent.java – Artem Bilan May 11 '20 at 13:42
  • Yes, it's in a different library and not part of the basic web dependency. For some reason Eclipse didn't know about that other library so it appeared not to exist. Usually it will offer to add the dependency. – David Bradley May 14 '20 at 15:30
  • You are a hero! – ata Dec 11 '20 at 05:11