Spring Websocket - 如何检测客户端断开连接

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;

    }

我需要检测客户端在客户端会话中断的情况。 实现ApplicationListener,但不清楚我如何注册侦听器? 我需要在我的web.xml文件中进行注册吗?

5个回答

15

WebSocketHandler 中的afterConnectionClosed函数在websocket客户端断开连接后被调用。您只需要以与重写handleTextMessage相同的方式进行覆盖即可。

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

客户端断开连接和服务器事件检测之间可能会存在很大的延迟。查看有关实时断开连接检测的详细信息


如何准确地覆盖和注册? - MrD
@MrD 你不需要注册。当连接关闭时,函数已经被调用。更新答案并提供简单的覆盖方法。 - mattm

5
您可以使用监听器来检测会话连接或关闭的情况。您可以通过此链接了解有关侦听器的更多信息:链接
以下是检测已连接会话的示例:
@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);
    }
}

如何检测会话断开的示例:

@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);
    }
}

谢谢您,弗拉基米尔。 - Pasha

5
你需要重写AbstractWebSocketMessageBrokerConfigurer的configureClientOutboundChannel和configureClientInboundChannel方法,提供你的拦截器。
另一种方法是使用ApplicationEvents。
这两种方法在此处都有描述: 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 + " ]");
}

我希望这有所帮助。如果需要更多解释,请告诉我。


1
您想要实现的可能是维护多个会话。类似于这样:
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 + "!"));
    }
}

1
这个实现应该注入到哪里? - MrD

0
将此代码粘贴到您的@SpringBootApplication或@Configuration注释的类中
@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());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接