8

I am new to spring

I have this class :

public class Server extends TextWebSocketHandler implements WebSocketHandler {

    WebSocketSession clientsession;
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {

        clientsession = session;

    }

I need to detect a client disconnect on clientsession. implement ApplicationListener but its not clear how I can register the listener? do I need to do it in my web.xml ?

Eli
  • 6,353
  • 9
  • 30
  • 25

5 Answers5

15

The WebSocketHandler afterConnectionClosed function is called after a websocket client disconnects. You simply need to override this in the manner that you override handleTextMessage.

@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus){
    // your code here
}

There may be substantial delay between the client disconnect and your server event detection. See details about real-time disconnection detection.

mattm
  • 5,851
  • 11
  • 47
  • 77
5

You will need to override configureClientOutboundChannel and configureClientInboundChannel of AbstractWebSocketMessageBrokerConfigurer, providing your interceptor

Another way is using ApplicationEvents.

Both methods are described here: http://www.sergialmar.com/2014/03/detect-websocket-connects-and-disconnects-in-spring-4/

public class StompConnectEvent implements ApplicationListener<SessionConnectEvent> {

private final Log logger = LogFactory.getLog(StompConnectEvent.class);

public void onApplicationEvent(SessionConnectEvent event) {
    StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());

    String  company = sha.getNativeHeader("company").get(0);
    logger.debug("Connect event [sessionId: " + sha.getSessionId() +"; company: "+ company + " ]");
}

}

I hope that help. Let me know if I need to explain more.

Amr K. Ismail
  • 368
  • 2
  • 9
4

You can use listeners to detect when session is connected or closed. More information about listeners you can find by this link.

Example how to detect connected session:

@Component
public class SessionConnectedEventListener implements ApplicationListener<SessionConnectedEvent> {

    private IWebSocketSessionService webSocketSessionService;

    public SessionConnectedEventListener(IWebSocketSessionService webSocketSessionService) {
        this.webSocketSessionService = webSocketSessionService;
    }

    @Override
    public void onApplicationEvent(SessionConnectedEvent event) {
        webSocketSessionService.saveSession(event);
    }
}

Example how to detect when session is disconneted:

@Component
public class SessionDisconnectEventListener implements ApplicationListener<SessionDisconnectEvent> {

    private IWebSocketSessionService webSocketSessionService;

    public SessionDisconnectEventListener(IWebSocketSessionService webSocketSessionService) {
        this.webSocketSessionService = webSocketSessionService;
    }

    @Override
    public void onApplicationEvent(SessionDisconnectEvent event) {
        webSocketSessionService.removeSession(event);
    }
}
Vladimir
  • 525
  • 5
  • 15
1

What you probably want to achieve is maintaining multiple sessions. Something like this:

public class Server extends TextWebSocketHandler implements WebSocketHandler {

    private List<WebSocketSession> sessions = new ArrayList<>();

    @Override 
    public void afterConnectionEstablished(WebSocketSession session) {
        sessions.add(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        sessions.remove(session);
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        // clientsession = session;
        // Send individual or broadcast messages here ...
        session.sendMessage(new TextMessage(textMessage + "!"));
    }
}
István Békési
  • 993
  • 4
  • 16
  • 27
0

Paste this code in your @SpringBootApplication or @Configuration annotated class

@EventListener
public void onDisconnectEvent(SessionDisconnectEvent event) {
    log.warn("Client with username {} disconnected", event.getUser().getName());
}

@EventListener
public void onConnectedEvent(SessionConnectEvent event) {
    log.warn("Client with username {} connected", event.getUser().getName());
}
FARS
  • 313
  • 6
  • 20