Spring Boot WebSocket:我如何知道客户端何时取消订阅? [英] Spring Boot WebSocket: How do I know when a Client has Unsubscribed?

查看:37
本文介绍了Spring Boot WebSocket:我如何知道客户端何时取消订阅?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个带有 STOMP 设置的简单 WebSocket,其中客户端连接到一个主题(带有 ID).控制器立即响应所请求的内容,并设置一个变量,指示客户端订阅的内容.一个用 @Scheduled 注释的方法,现在每隔几秒就会向客户端发送它所请求的内容.

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

我如何知道客户是否已取消订阅?如果存在类似于 @UnsubscribeMapping 的内容,我可以简单地将 currentSubscriptionServiceId 变量再次设置为 null,从而阻止计划方法连续发布数据.

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.

推荐答案

你可以像这样监听 SessionUnsubscribeEvent 事件:

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

这篇关于Spring Boot WebSocket:我如何知道客户端何时取消订阅?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆