Spring spring方法

时间:2017-11-02 15:31:36

标签: spring websocket spring-integration

我在Spring组件中有方法,它从Spring Integration通道接收消息。收到消息后,会将其发送到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 - 处理MESSAGE目的地= / topic / update session = null payload = {XXX} .14:01:19.939 [http-nio-8080-exec-4] DEBUG o.s.m.s.b.SimpleBrokerMessageHandler - 广播到1个会话。

当它不起作用时,第二条消息不存在。 (thread是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);

UPDATE     我在我的环境中添加了Spring消息源代码并实现了以下内容:运行时中有两个SimpleBrokerMessageHandler类实例。对于工作副本,subscriptionregistry有一个条目,对于非工作条目,它有0个订阅。这是否为问题的根本原因提供了线索?只定义了一个MessageSendingOperations变量,它位于控制器上。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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";
    };
}

我有这个DEBUG日志:

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中查看更多信息。