【问题标题】:Spring getting events from the MQTT outbound channel adapterSpring 从 MQTT 出站通道适配器获取事件
【发布时间】:2014-07-21 12:13:23
【问题描述】:

我已经在使用 Spring Integration 4.1.0 SNAPSHOT。

我有这个 MQTT 出站适配器:

<int-mqtt:outbound-channel-adapter
        async="true"
        async-events="true"
        id="mqttOutput"
        channel="httpInputChannel"
        client-id="#{controller.mqttPublisherConfig.clientID}"
        url="#{controller.mqttPublisherConfig.completeURL}"
        default-qos="#{controller.mqttPublisherConfig.qosString}"
        default-retained="#{controller.mqttPublisherConfig.retainFlag}"
        default-topic="#{controller.mqttPublisherConfig.topic}"
        />

现在在我的控制器(MVC 应用程序)中,我想接收适配器发出的事件。

我正在实施 ApplicinListener:

    @Controller
    public class ServletController implements ApplicationListener {

        public void onApplicationEvent(ApplicationEvent event)
        {
         //
        }

        ...
    }

仍然,我没有收到来自 MQTT 适配器的任何事件。

实现一个 in-event:inbound-channel-adapter 是可行的,但是:

<int-event:inbound-channel-adapter channel="eventLogger" 
                               error-channel="eventErrorChannel"
                               />

但我真的很想处理代码中的事件!

【问题讨论】:

    标签: java spring spring-mvc spring-integration mqtt


    【解决方案1】:

    您的@Controller 是否与 MQTT 适配器位于相同的应用程序上下文中?或者(最常见的情况),控制器位于 web (DispatcherServlet's) 上下文中,而其他 bean 位于由 ContextLoaderListener 加载的根应用程序上下文中。

    问题是根上下文中的 bean 无法“看到”servlet 上下文中的 bean,并且在根上下文中发布的事件不会被子上下文中的侦听器接收。

    您将不得不颠覆这个可见性问题 - 要么将业务 bean 移动到 Web 上下文中(通常不推荐,但对于小型应用程序来说并不可怕),或者以某种方式将侦听器从根上下文连接到控制器 - 可能通过连接它进入控制器并让控制器在初始化期间将自身传递给侦听器(afterPropertiesSet())。你会有一个类缠结(相互依赖),但它应该可以工作。

    顺便说一句,ApplicationListener 可以接受泛型所以

    public class MyListener implements ApplicationListener<MqttIntegrationEvent> { ... }
    

    只会获得 MQTT 事件。

    编辑:

    另一种解决方案是使用事件通道适配器并将outbound-channel-adapter 添加到 Web 上下文(与控制器相同的上下文)...

    @Controller
    ...
    
        public void onMqttEvent(MqttIntegrationEvent event) { ... }
    
    
    <int:outbound-channel-adapter channel="eventLogger"
        ref="myController" method="onMqttEvent" />
    

    它将在根上下文中对通道可见。

    确保将事件适配器配置为仅接收 MqttIntegrationEvents。

    【讨论】:

    • 添加了另一个解决方案。
    • 确实,我认为这一定是可见性问题。还记得我之前的问题吗?:stackoverflow.com/questions/24683524/… 我正在为每个请求创建一个新的上下文(在地图中跟踪上下文),所以我认为将 bean 移动到 servlet-context 不是正确的方法?你的第二种方法看起来很有希望。我实际上已经考虑过拦截事件通道或添加一些服务激活器或其他东西......我会尝试第二种方法并尽快回复您。 PS:谢谢一百万!
    • 如果你将控制器的上下文作为 mqtt 上下文的父上下文,在每个 mqtt 上下文中放置一个事件入站适配器,配置为发送到控制器上下文中的通道,该通道具有 &lt;outbound-channel-adapter/&gt; 引用你的控制器方法,一切都应该很好。
    猜你喜欢
    • 2016-07-19
    • 2015-03-21
    • 2015-07-11
    • 2014-05-31
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2011-08-29
    • 2012-09-24
    相关资源
    最近更新 更多