Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you quickly close a nonresponsive websocket in Java Spring Tomcat?

I have a real-time application with clients using websockets to connect with a Spring Framework server, which is running Spring Boot Tomcat. I want the server to quickly (within 5 seconds) detect when a client stops responding due to a network disconnect or other issue and close the websocket.

I have tried

  1. Setting the max session idle timeout as described in the documentation as "Configuring the WebSocket Engine" 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;
    }
    

I am not sure this is implemented correctly because I do not see the link between the ServletServerContainerFactoryBean and my generation of ClientHandlers.

  1. Sending ping messages from server every 2.5 seconds. After I manually disconnect the client by breaking the network connection, the server happily sends pings for another 30+ seconds until a transport error appears.

  2. 1 and 2 simultaneously

  3. 1 and 2 and setting server.session-timeout = 5 in application.properties

My methodology for testing this is to:

  1. Connect a websocket from a laptop client to the Tomcat server
  2. Turn off network connection on the laptop using the physical switch
  3. Wait for Tomcat server events

How does a Spring FrameworkTomcat server quickly detect that a client has been disconnected or not responding to close the websocket?

like image 436
mattm Avatar asked Oct 04 '14 12:10

mattm


People also ask

How long does WebSocket stay open?

However, the connection between a client and your WebSocket app closes when no traffic is sent between them for 60 seconds.

Does WebSocket close on page refresh?

User presses refresh. Browser closes down all resources associated with the original page, including closes the webSocket connection.

What is default timeout WebSocket?

A WebSocket times out if no read or write activity occurs and no Ping messages are received within the configured timeout period. The container enforces a 30-second timeout period as the default.


1 Answers

The approach I eventually took was to implement an application-layer ping-pong protocol.

  • The server sends a ping message with period p to the client.
  • The client responds to each ping message with a pong message.
  • If the server sends more than n ping messages without receiving a pong response, it generates a timeout event.
  • The client can also generate a timeout event if it does not receive a ping message in n*p time.

There should be a much simpler way of implementing this using timeouts in the underlying TCP connection.

like image 158
mattm Avatar answered Oct 12 '22 09:10

mattm