Search code examples
spring-mvcnginxspring-webfluxhaproxyspring-restcontroller

Spring detect if client disconnect


This is the current architecture, I am working with

        (upload file)                          (WebClient RestAPI)    (Rest API)
Browser --------------> HAProxy ----> Nginx -----> Spring WebFlux ---> Spring MVC

I would like to send a request to remove cache from the server's Redis if Browser got disconnected by

  • client's PC shutdown
  • xhr abortion (AJAX, etc)
  • browser's tab is closed
  • losing the internet connection
  1. Technically, can I possibly send a request to remove some cache in the server after the server detected the browser got disconnected? as the below
   eventClientDisconnect () {
       // remove some cache from Redis
       http.send('DELETE', 'http://localhost/user/1')
   }
  1. Which is the best layer that I should trigger if the browser got disconnect?
    HAProxy, Nginx, WebFlux, or MVC?

Thank you.

I apologize in advance if those questions are not appropriate.


Solution

  • I found the solutions.
    I can handle it in Webflux or MVC servlet.

    I.MVC Servlet can be detected (when the request was finished)

    • Client closes browser or tab
    • Client PC's shutdown
    • AJAX abortion
    • Client disconnect by switching off the WiFi
    @Bean
    public Filter loggingFilter(){
        AbstractRequestLoggingFilter f = new AbstractRequestLoggingFilter() {
    
            @Override
            protected void beforeRequest(HttpServletRequest request, String message) {
                System.out.println("beforeRequest: " +message);
            }
    
            @Override
            protected void afterRequest(HttpServletRequest request, String message) {
                       // Client closes browser or tab
                       // Client PC's shutdown
                       // AJAX abortion
                       // Client disconnect by switching off the WiFi
            }
        };
        return f;
    }
    

    For any more details

    II.Webflux can be detected only

    • Client closes browser or tab
    • Client PC's shutdown
    • AJAX abortion

    you use doFinally { ... } event to handle the above problems is enough.

    But if you wish to handle client disconnect by switching off the WiFi.
    You may need to use the WebSocket dependency.

    This code may be working in Servlet not Webflux, but I am not sure, so you can try it.

    Server

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-websocket'
    }
    
    public class GreetingHandler extends TextWebSocketHandler {
    
        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            super.afterConnectionClosed(session, status);
            // Detected client disconnect here....
        }
    }
    
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
            super.afterConnectionEstablished(session);
            // Detected client connect here....
        }
    
        @Override
        protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
             session.sendMessage(message);
        }
    
    
    @Configuration
    @EnableWebSocket
    public class RawWebSocketConfiguration {
        @Bean
        public WebSocketConfigurer webSocketConfigurer() {
            return new WebSocketConfigurer() {
                @Override
                public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
                    registry.addHandler(new GreetingHandler(), "/greeting").setAllowedOrigins("http://localhost:7010");
                }
            };
        }
    }
    

    Client JS (http://localhost:7010)

    const socket = new WebSocket("ws://localhost:7000/greeting");