使用Stomp代理中继进行Web套接字消息传递,我可以订阅目标/topic/mydest
。这将创建一个代理订阅,并接收系统中某些内容触发此代理目标的所有消息,这种情况发生在系统中的某些事件发生时。
我可以订阅目标/app/mydest
,并且将调用带有@SubscribeMapping("mydest")
的控制器方法,并且返回值仅作为消息在此套接字上发回。据我所知,这是唯一将为此订阅发送的消息。
有没有办法在单个订阅中组合它,即为某个/topic
目的地创建代理订阅,和触发一些直接将消息发送回订阅者的代码?
用例:当系统发生错误时,会将具有当前错误计数的消息发送到/topic/mydest
。当新客户订阅时,我只想向他发送最后已知的错误计数。其他人对此刻并不感兴趣,因为伯爵没有改变。
我目前的解决方案是订阅/app/mydest
和/topic/mydest
,并在客户端上使用相同的消息处理程序。但它确实是一个逻辑订阅,并且它有点容易出错,因为客户需要记住订阅它们。
我在这方面的问题:是否会有/app/
订阅的进一步消息?有没有什么可以触发一个?如何向主机的订户发送初始信息,而不向现有订户发送冗余消息?
根据要求,这是我的Websocket配置类。
@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableStompBrokerRelay("/queue/", "/topic/", "/exchange/");
registry.setApplicationDestinationPrefixes("/app");
}
}
答案 0 :(得分:0)
您可以使用ApplicationListener和SessionSubscribeEvent。 例如:
@Component
public class SubscribeListener implements ApplicationListener<SessionSubscribeEvent> {
private final SimpMessagingTemplate messagingTemplate;
@Autowired
public SubscribeListener(SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
@Override
public void onApplicationEvent(SessionSubscribeEvent event) {
messagingTemplate.convertAndSendToUser(event.getUser().getName(), "/topic/mydest", "Last known error count");
}
}
答案 1 :(得分:0)
您可以监听会话订阅事件并发送初始消息
@Component
@RequiredArgsConstructor
public class WebSocketEventListener {
private static final Logger logger = LoggerFactory.getLogger(WebSocketEventListener.class);
private final SimpMessagingTemplate simpMessagingTemplate;
@EventListener
public void handleSessionSubscribeEvent(SessionSubscribeEvent event) {
logger.info("Subscribed to session: " + event);
Principal user = event.getUser();
if (user instanceof UsernamePasswordAuthenticationToken) {
UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) user;
if (token.getPrincipal() instanceof UserDetails) {
UserDetails userDetails = (UserDetails) token.getPrincipal();
simpMessagingTemplate.convertAndSendToUser(userDetails.getUsername(), "/queue/notify", "Hello");
}
}
}
}