【问题标题】:Spring Mqtt - Publish messages to multiple topics programmaticallySpring Mqtt - 以编程方式将消息发布到多个主题
【发布时间】:2015-07-20 02:54:29
【问题描述】:

如何以编程方式发布具有不同主题的消息?

<mqtt:outbound-channel-adapter id="mqttOut" 
    auto-startup="true" 
    client-id="foo"
    url="tcp://localhost:1883"
    client-factory="clientFactory"
    default-qos="0"
    default-retained="false"
    default-topic="bar"
    async="true"
    async-events="true" />

我尝试了Spring integration MQTT publish & subscribe to multiple topics,但无法配置。

还尝试了MqttPahoMessageHandlerAdapter,它有一个publish(),但有protected

使用org.eclipse.paho.client.mqttv3.MqttAsyncClientorg.eclipse.paho.client.mqttv3.MqttCallback 非常简单。但我想一直坚持春天。

如果有人能指出我正确的方向,不胜感激。

【问题讨论】:

    标签: spring spring-integration mqtt paho


    【解决方案1】:

    无论如何,您都可以使用 Spring Integration 做到这一点!拥有大量 EIP 组件实现和板载 Spring 功能(注入、SpEL 等),再加上一点想象力,即使没有任何 Java 代码,我们也可以达到任何最终应用程序的要求。

    因此,&lt;mqtt:outbound-channel-adapter&gt; 允许在运行时确定 topic。您应该提供 MqttHeaders.TOPIC MessageHeader 而不是 default-topic

    因此,如果您需要向多个主题发送相同的消息,您只需为每个主题构建该消息的副本。 &lt;splitter&gt; 可以帮助我们:

    <int:splitter input-channel="enricheMessage" output-channel="sendMessage" apply-sequence="false">
        <int-groovy:script>
            ['topic1', 'topic2', 'topic3'].collect {
                org.springframework.integration.support.MessageBuilder.withPayload(payload)
                        .copyHeaders(headers)
                        .setHeader(org.springframework.integration.mqtt.support.MqttHeaders.TOPIC, it)
                        .build()
            }
        </int-groovy:script>
    </int:splitter>
    

    sendMessage可以是ExecutorChannel,实现并行发布。

    更新

    您可以在&lt;splitter&gt; 上使用refmethod,使用类似的Java 代码实现相同的迭代和消息丰富逻辑。 当然,即使使用 SpEL 也可以做到这一点,但使用 Collection Projection 会看起来有点复杂。

    【讨论】:

    • 我的主题会根据我的场景在运行时动态生成。我对 groovy 的了解为 0 :(。我想要实现的是,服务器(一个线程)应该能够在需要时向动态主题发送消息。例如,我想在 23:59 发布一组消息午夜到主题“a”、“b”和“c”。我第二天,这些主题可能会改变。
    • 所以,你可以通过一些 Java 代码来做到这一点。并在&lt;splitter&gt; 上使用refmethod。并执行与我在 Groovy 代码中展示的完全相同的操作:迭代您的动态主题并为每个主题返回带有适当 MqttHeaders.TOPIC 标头的 List&lt;Message&lt;?&gt;&gt;。不幸的是,&lt;publish-subscribe-channel&gt;(Gary 的示例)对您没有帮助...
    • 你能解释一下为什么选择&lt;splitter&gt;吗? &lt;splitter&gt; 有比&lt;publish-subscribe-channel&gt; 更多的功能吗?在 spring 文档中 Splitter 是一个组件,其作用是将消息划分为多个部分,并将生成的消息发送到独立处理。。在这种情况下,我没有任何要分区的消息。但我有几条消息要发送。
    • 对于&lt;publish-subscribe-channel&gt;,您必须拥有带有预定义topics 的固定订阅者。使用&lt;splitter&gt;,您将拥有多条消息,并将它们全部发送到具有自己的topic 的同一适配器。是的,这样拆分看起来有点吓人,但是没有选择为多个运行时主题分发相同的消息。
    • 好吧,你做了我在回答中指出的相同迭代。 `` 在这里有什么好处?你有相同的&lt;mqtt:outbound-channel-adapter&gt;,而且只有一个。 Gary 之所以提到它,是因为他建议为每个主题设置多个 &lt;mqtt:outbound-channel-adapter&gt;s。
    【解决方案2】:

    声明一个&lt;publish-subscribe-channel id="toMqtt" /&gt;;将其设置为每个出站通道适配器上的channel 属性;消息将被发送到每个适配器。

    【讨论】:

    • 非常感谢。这是工作。我还尝试了&lt;channel id="myPublisher"/&gt;&lt;bridge input-channel="myPublisher" output-channel="IdOfMqttOutBoundAdapter"/&gt;。这也奏效了。但我不得不从&lt;mqtt:outbound-channel-adapter id="IdOfMqttOutBoundAdapter" /&gt; 中删除async-events="true"
    猜你喜欢
    • 2020-09-15
    • 2022-11-14
    • 2016-04-05
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 2022-11-11
    • 1970-01-01
    相关资源
    最近更新 更多