Search code examples
javaspringspring-mvcwebsocketspring-websocket

How to stop the spring MVC controller execution if client close the browser tab?


I'm developing a web app that use a spring websocket connection to send multiple message to a specific user. I've got a spring mvc controller which when receive a STOMP from the client start sending message to the user. It's something like this:

@Controller
public class Controller{
     @Autowired
     private SimpMessagingTemplate template;

     @MessageMapping("/")
     @SendToUser("/queue/user")
     public void myMethod(ClientMessage msg, Principal principal){
          Object myObject = new Object();
          //stuff
          while(true){
               //more stuff
               this.template.convertAndSendToUser(principal.getName(), "/queue/user", myObject);
          }
     }
}

Now my question is: there's a way to know when the client close (or reload) the browser tab? I want to exit from the while cycle when the client close the tab to terminate the controller execution. I was thinking to stop the while cycle by checking something, like: while(!session.isClose()) Can anyone help me out with this problem?


Solution

  • I post my solution if anyone could need it.

    I don't really know if i'm doing things correctly but i moved the SessionDisconnectEvent listener from a specific class to my controller. So, now the controller implements the ApplicationListener and override the onApplicationEvent. When the user close the tab a boolean is setted to true and the controller stops its execution. Now i've got something like this:

    @Controller
    public class Controller implements ApplicationListener<SessionDisconnectEvent>{
    
         @Autowired
         private SimpMessagingTemplate template;
    
         private boolean disconnected;
    
         @MessageMapping("/")
         @SendToUser("/queue/user")
         public void myMethod(ClientMessage msg, Principal principal){
              Object myObject = new Object();
              //stuff
              while(!disconnected){
                   //more stuff
                   this.template.convertAndSendToUser(principal.getName(), "/queue/user", myObject);
              }
         }
    
         @EventListener
         @Override
         public void onApplicationEvent(SessionDisconnectEvent  applicationEvent) {
              System.out.println("SESSION " + applicationEvent.getSessionId() + " DISCONNECTED");
              this.graphService.setDisconnect(true);
         }
    }