gpt4 book ai didi

spring - 使用 Spring 踩踏 websocket 和 sockJS 消息丢失

转载 作者:行者123 更新时间:2023-12-02 03:19:02 25 4
gpt4 key购买 nike

在客户端 javascript 我有

    stomp.subscribe("/topic/path", function (message) {
console.info("message received");
});

在服务器端

public class Controller {
private final MessageSendingOperations<String> messagingTemplate;
@Autowired
public Controller(MessageSendingOperations<String> messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
@SubscribeMapping("/topic/path")
public void subscribe() {
LOGGER.info("before send");
messagingTemplate.convertAndSend(/topic/path, "msg");
}
}

通过此设置,我偶尔(大约每 30 次页面刷新一次)会遇到消息丢失的情况,这意味着我既看不到客户端上的“已收到消息”消息,也看不到来自 Chrome 调试工具的 Websocket 流量。

“发送之前”始终记录在服务器端。

当我在 subscribe() 方法中调用 MessageSendingOperations 时,它看起来好像尚未准备好。 (如果我在调用 messagesTemplate.convertAndSend 之前放置 Thread.sleep(50); ,问题就会消失(或者不太可能重现))

我想知道以前是否有人经历过同样的情况,以及是否有一个事件可以告诉我 MessageSendingOperations 是否已准备好。

最佳答案

您面临的问题在于 clientInboundChannel 的本质,默认情况下是 ExecutorSubscribableChannel

它有 3 个订阅者:

0 = {SimpleBrokerMessageHandler@5276} "SimpleBroker[DefaultSubscriptionRegistry[cache[0 destination(s)], registry[0 sessions]]]"
1 = {UserDestinationMessageHandler@5277} "UserDestinationMessageHandler[DefaultUserDestinationResolver[prefix=/user/]]"
2 = {SimpAnnotationMethodMessageHandler@5278} "SimpAnnotationMethodMessageHandler[prefixes=[/app/]]"

它们是在taskExecutor内调用的,因此是异步的。

这里的第一个(SimpleBrokerMessageHandler)(或者StompBrokerRelayMessageHandler)如果你使用broker-relay)负责注册订阅主题

您的 messagingTemplate.convertAndSend(/topic/path, "msg") 操作可能会在该 WebSocket session 的订阅注册之前执行,因为它们是在单独的线程中执行的。因此,Broker 处理程序不知道您是否将消息发送到 session 。

可以在带有 return 的方法上配置 @SubscribeMapping,该方法的结果将作为对该订阅的回复发送在客户端上运行。

HTH

关于spring - 使用 Spring 踩踏 websocket 和 sockJS 消息丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29194530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com