【问题标题】:WebSocket message not broadcast when sent by spring integration methodSpring集成方法发送WebSocket消息时不广播
【发布时间】:2018-04-15 04:45:27
【问题描述】:

我在一个 Spring 组件中有一个方法,它从 Spring 集成通道接收消息。收到消息后,会将其发送到 WebSocket 端点。这行不通。消息未广播。

this.messagingTemplate.convertAndSend("/topic/update", dto);

但是,当我将相同的代码放入 Web 控制器并在其上放置一个 RequestMapping 并调用该端点时,它就可以工作了。消息被广播。

当 Spring 集成执行程序调用它时,可能导致它无法工作的原因是什么?

当它工作时:.14:01:19.939 [http-nio-8080-exec-4] DEBUG o.s.m.s.b.SimpleBrokerMessageHandler - 处理消息目的地=/主题/更新会话=空负载={XXX} .14:01:19.939 [http-nio-8080-exec-4] 调试 o.s.m.s.b.SimpleBrokerMessageHandler - 广播到 1 个会话。

当它不起作用时,第二条消息不存在。 (线程是 taskExecutor-1 而不是 http-nio..)

控制器代码:

@RequestMapping("/testreq")
public void updateDelta() {
    SummaryDTO dto = new SummaryDTO();
    dto.setValue(-5000.0);
    dto.setName("G");

    this.messagingTemplate.convertAndSend("/topic/update", dto);

}

//this method is called by Spring Integration
//created by serviceActivator = new 
//ServiceActivatingHandler(webcontroller,"update");
public void updateDelta(SummaryDTO dto) {       
  this.messagingTemplate.convertAndSend("/topic/update", dto);

 }

消息发送:

synchronized(this){
...

this.updatedcontrollerchannel.send(MessageBuilder.withPayload(summarydto).build( )); }

频道创建:

updatedchannel = new DirectChannel();
updatedchannel.setBeanName("updatedcontroller");

serviceActivator = new ServiceActivatingHandler(detailService,"update");
handlerlist.add(serviceActivator);
updatedchannel.subscribe(serviceActivator);
beanFactory.registerSingleton("updatedcontroller", channel);

更新 我在我的环境中添加了 spring 消息传递源代码并实现了以下功能: 运行时中有 2 个 SimpleBrokerMessageHandler 类的实例。对于工作副本订阅注册表有一个条目,对于非工作副本,它有 0 个订阅。这是否为问题的根本原因提供了线索?只定义了一个 MessageSendingOperations 变量,它在控制器上。

【问题讨论】:

    标签: spring websocket spring-integration


    【解决方案1】:

    应该是SimpMessageSendingOperations未正确注入的问题。

    这个由AbstractMessageBrokerConfiguration.brokerMessagingTemplate() @Bean 填充。

    不过,我建议您查看 Spring Integration 中的 WebSocketOutboundMessageHandlerhttps://docs.spring.io/spring-integration/docs/4.3.12.RELEASE/reference/html/web-sockets.html

    更新

    这在测试用例中对我有用:

    @Bean
    @InboundChannelAdapter(channel = "nullChannel", poller = @Poller(fixedDelay = "1000"))
    public Supplier<?> webSocketPublisher(SimpMessagingTemplate brokerMessagingTemplate) {
        return () -> {
            brokerMessagingTemplate.convertAndSend("/topic/foo", "foo");
            return "foo";
        };
    }
    

    我有这个调试日志:

    12:57:27.606 DEBUG [task-scheduler-1][org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler] Processing MESSAGE destination=/topic/foo session=null payload=foo
    12:57:27.897 DEBUG [clientInboundChannel-2][org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler] Processing SUBSCRIBE /topic/foo id=subs1 session=941a940bf07c47a1ac786c1adfdb6299
    12:57:40.797 DEBUG [task-scheduler-1][org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler] Processing MESSAGE destination=/topic/foo session=null payload=foo
    12:57:40.798 DEBUG [task-scheduler-1][org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler] Broadcasting to 1 sessions.
    

    Spring Integration 一切正常。

    这就是为什么我要求你的整个 Spring Boot 应用程序从我们这边运行。

    更新 2

    当您开发 Web 应用程序时,请务必将所有配置上下文合并到一个应用程序上下文 - WebApplicationContext

    如果不需要应用程序上下文层次结构,应用程序可以通过getRootConfigClasses() 返回所有配置,并从getServletConfigClasses() 返回 null。

    在 Spring Framework Reference Manual 中查看更多信息。

    【讨论】:

    • 但是,我在 Web 控制器中尝试了相同的操作。我在 Web 控制器上定义了由 SI 通道调用的相同方法。 SI 通道消费的消息没有被广播,但是当一个 http 请求被映射到控制器时,消息被广播了。完全相同的方法调用:this.messagingTemplate.convertAndSend("/topic/update", dto);调试日志中没有看到错误。 (更新问题)
    • 好的!请与我们分享您的 Spring Boot 应用程序来玩。或者至少一些简单的代码来理解如何从我们这边重现。谢谢
    • Websocket 部分与 Spring 集成无关。它是 MVC 应用程序的一部分。有一个适当的配置类扩展 AbstractWebSocketMessageBrokerConfigurer 以便 web 控制器请求触发的转换和发送工作。
    • 好吧,没有足够的代码。展示你的类以及如何从 Spring Integration 中使用它。
    • 在我的回答中查看更新。
    【解决方案2】:

    我找到了问题的原因。具有 @EnableWebSocketMessageBroker 注解的类被加载了两次,并导致创建了两个 SimpleBrokerMessageHandler 实例。 @Artem Bilan:感谢您的宝贵时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      • 2019-07-24
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多