一尘不染

如何在Java Spring Tomcat中快速关闭无响应的websocket?

tomcat

我有一个实时应用程序,其中的客户端使用websockets与运行Spring Boot Tomcat的Spring
Framework服务器连接。我希望服务器快速(在5秒内)检测到客户端由于网络断开或其他问题而停止响应的时间,然后关闭websocket。

我努力了

  1. 如文档“配置WebSocket引擎”中所述设置最大会话空闲超时 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
        @Bean
    public WebSocketHandler clientHandler() {
        return new PerConnectionWebSocketHandler(ClientHandler.class);
    }
    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = 
            new ServletServerContainerFactoryBean();
        container.setMaxSessionIdleTimeout(5000);
        container.setAsyncSendTimeout(5000);
        return container;
    }

我不确定此实现是否正确,因为我看不到ServletServerContainerFactoryBean与我的ClientHandlers之间的链接。

  1. 每2.5秒从服务器发送一次ping消息。在通过断开网络连接手动断开客户端连接后,服务器会愉快地发送ping命令30秒钟以上,直到出现传输错误。

  2. 同时1和2

  3. 1和2并server.session-timeout = 5在application.properties中进行设置

我的测试方法是:

  1. 将Websocket从便携式计算机客户端连接到Tomcat服务器
  2. 使用物理交换机关闭笔记本电脑上的网络连接
  3. 等待Tomcat服务器事件

Spring FrameworkTomcat服务器如何快速检测到客户端已断开连接或没有响应以关闭websocket?


阅读 629

收藏
2020-06-16

共1个答案

一尘不染

我最终采用的方法是实现应用程序层乒乓协议。

  • 服务器向p客户端发送带有周期的ping消息。
  • 客户端以pong消息响应每个ping消息。
  • 如果服务器发送了多个nping消息而未收到pong响应,则它将生成一个超时事件。
  • 如果客户端未及时收到ping消息,则客户端也可以生成超时事件n*p

应该使用更简单的方法在基础TCP连接中使用超时来实现此目的。

2020-06-16