Spring Boot WebSocket: Как узнать, когда клиент отписался? - PullRequest
0 голосов
/ 01 марта 2019

В настоящее время у меня есть простой WebSocket с настройкой STOMP, где клиент подключается к теме (с идентификатором).Контроллер немедленно отвечает тем, о чем просили, и устанавливается переменная, указывающая, на что подписан клиент.Метод, помеченный @Scheduled, теперь отправляет клиенту то, что он запрашивал каждые несколько секунд.

Запланированный метод ничего не делает, пока клиент не подключится в первый раз.Однако после первой подписки публикация будет продолжена независимо от того, подписан клиент или нет.

@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();
            }
        });
    }
}

Как узнать, отписался ли клиент?Если существует что-то похожее на @UnsubscribeMapping, я мог бы просто снова установить переменную currentSubscriptionServiceId в null, не позволяя запланированному методу публиковать данные непрерывно.

1 Ответ

0 голосов
/ 01 марта 2019

Вы можете прослушать событие SessionUnsubscribeEvent так:

@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
       }
   }
}
...