我目前有一个具有STOMP设置的简单WebSocket,其中客户端连接到主题(具有ID)。控制器立即响应要求的内容,并设置了一个变量来指示客户端已订阅的内容。@Scheduled现在,带有注释的方法每隔几秒钟就会向客户端发送一次请求。
@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再次设置为,以防止调度的方法连续发布数据。
@UnsubscribeMapping
currentSubscriptionServiceId
null
您可以SessionUnsubscribeEvent像这样收听事件:
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 } } }