我可以使用WebSocketMessageBrokerConfigurer和SimpleMessageBroker配置向特定用户发送消息,它运行良好。
问题:当某人订阅特定的userId时,我想将以前的消息从数据库发送到该订阅者。但是如果已经存在具有相同userId的连接和订阅(例如,用户从另一设备/浏览器登录),旧订户也将从DB接收初始消息。对于每个具有相同userId的新订阅者,旧订阅者将收到相同的消息。
那么,如何将初始消息从数据库发送到特定的会话,而不是所有的会话?STOMP协议是否可以实现这一点?
下面是代码:
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp/message").setAllowedOrigins("*");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/chatroom", "/user");
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/user");
}
}
public class MessageController {
@MessageMapping("/private-message")
private void receivePrivateMessage(
@Payload Message message,
Principal user,
@Header("simpSessionId") String sessionId) {
log.info("server received private message: " + message);
simpMessagingTemplate.convertAndSendToUser(message.getReceiverId().toString(), "/private-message", message);
}
}
public class EventSubscribeListener implements ApplicationListener<SessionSubscribeEvent> {
private final SimpMessagingTemplate simpMessagingTemplate;
@Override
public void onApplicationEvent(SessionSubscribeEvent event) {
log.info("Stomp subscribed");
TODO get messages from db and send initial messages from db to to specific session/subscriber
}
}
我唯一的想法是我可以将基于userId的订阅替换为基于sessionId的订阅。但这意味着前端必须获取sessionId并订阅它。我不想让FE来处理这个。
1条答案
按热度按时间yftpprvb1#
可以使用
@SubscribeMapping
:@SubscribeMapping类似于@MessageMapping,但将Map范围缩小到仅订阅消息。它支持与@MessageMapping相同的方法参数。但是对于返回值,默认情况下,消息直接发送给客户端(通过clientOutboundChannel,响应订阅),而不是发送给broker(通过brokerChannel,作为匹配订阅的广播)。添加@SendTo或@SendToUser会覆盖此行为并改为发送到代理。