Spring Boot WebSocket: How do I know when a Client has Unsubscribed?

旧时模样 提交于 2019-12-08 12:28:44

问题


I currently have a simple WebSocket with STOMP setup where a client connects to a topic (with an ID). The controller immediately responds with what was asked for, and a variable is set indicating what the client has subscribed to. A method, annotated with @Scheduled, now sends to the client what it has requested every few seconds.

The scheduled method does not do anything until the client has connected for the first time. However, after the first subscription it will continue publishing regardless of whether a client is subscribed or not.

@Controller
public class ServiceWebSocketController {

    @Autowired
    private ServiceService serviceService;

    @Autowired
    WebSocketSessionController webSocketSessionController;

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    private Set<Long> services = new HashSet<>();

    @SubscribeMapping("/service/{serviceId}")
    public ServiceDTO subscribe(@DestinationVariable("serviceId") final Long serviceId) throws SQLException {
        System.out.println("Subscribed to Service with ID: " + serviceId);
        services.add(serviceId);
        return serviceService.getServiceWithProperties(serviceId).orElseThrow(() -> new ResourceNotFoundException("Service", "id", serviceId));
    }

    @Scheduled(fixedDelay = 2000)
    public void service() throws SQLException {
        services.removeIf(serviceId -> !webSocketSessionController.hasSubscriptionTo("/topic/service/" + serviceId));

        // Publish specified Service data to each anonymously subscribed client.
        services.forEach(serviceId -> {
            try {
                System.out.println("Publishing Service with ID: " + serviceId);
                // We don't use .convertAndSendToUser here, because all our clients are anonymous.
                simpMessagingTemplate.convertAndSend("/topic/service/" + serviceId, serviceService.getServiceWithProperties(serviceId));
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
    }
}

How can I tell if the client has unsubscribed? If something similar to @UnsubscribeMapping exists, I could simply set the currentSubscriptionServiceId variable to null again, preventing the scheduled method to publish data continuously.


回答1:


You can listen to the event SessionUnsubscribeEvent like this:

@Controller
public class SessionUnsubscribeListener implements ApplicationListener<SessionUnsubscribeEvent> {

   @Override
   public void onApplicationEvent(SessionUnsubscribeEvent event) {
       GenericMessage message = (GenericMessage) event.getMessage();

       String simpDestination = (String) message.getHeaders().get("simpDestination");

       if ("/topic/service".equals(simpDestination)) {
           // do stuff
       }
   }
}


来源:https://stackoverflow.com/questions/54946096/spring-boot-websocket-how-do-i-know-when-a-client-has-unsubscribed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!