【问题标题】:Wildfly 18, MQTT and wildcard subscriptionsWildfly 18、MQTT 和通配符订阅
【发布时间】:2020-02-23 17:32:51
【问题描述】:

我正在尝试让 Wildfly 18 服务器的 Apache Artemis 中的 MQTT 接受器运行。

服务器正在运行,我什至可以将消息发送到已定义的主题(尽管必须定义)。

最初我必须将权限create-durable-queue="true" 添加到安全性,否则,一旦我尝试订阅该主题,服务器就会终止通信。

也就是说,我试图弄清楚如何在 JMS 端创建一个带有通配符的主题订阅,但我既找不到当前文档,也找不到任何其他相关信息。

为用例提供一些背景知识:

我想使用 Wildfly 18 的内置 Artemis 服务器,并且有一堆设备可以发布到 /device/reader/SOMEID/temperature 等主题。

在我的 EJB 中,我想订阅主题 /device/# 并获取该主题和所有子主题的所有消息。

我怎样才能做到这一点?

当我在配置中的条目是

<jms-topic name="TestTopic" entries="java:/jms/topic/TestTopic" />

为什么是 MQTT 主题然后是 jms/topic/TestTopic?我不喜欢在那里使用前缀。

【问题讨论】:

  • 我的回答是否解决了您的问题?如果是这样,请将其标记为正确,以帮助将来有相同问题的其他用户。如果不是,请详细说明原因。谢谢!

标签: jms wildfly mqtt activemq-artemis wildfly-18


【解决方案1】:

服务器正在运行,我什至可以将消息发送到已定义的主题(尽管必须定义)。

如果您将true 用于auto-create-addresses address-setting,那么当您向其发送消息或在其上创建订阅时,应自动为您创建主题(即地址)。

最初我必须将权限 create-durable-queue="true" 添加到安全性,否则,一旦我尝试订阅该主题,服务器就会终止通信。

这是预期的,因为默认情况下未设置create-durable-queue 权限。

如果您希望 JMS 主题订阅者将所有消息发送到特定地址集,则只需在服务器配置或代码中的 jms-topic 定义中指定所需的通配符地址。您可以找到有关 ActiveMQ Artemis here 的有关此主题的最新文档以及使用它的示例 here

为什么是 MQTT 主题,然后是 jms/topic/TestTopic?我不喜欢在那里使用前缀。

不幸的是,Wildfly 中的前缀不是可选的,因为存在历史向后兼容性问题。此外,虽然嵌入式 ActiveMQ Artemis 实例在技术上可以为非 JMS 客户端提供服务,但嵌入式代理实际上只是作为 Java EE 要求的 JMS 实现。如果您独立运行 ActiveMQ Artemis,您将拥有更大的灵活性(即不使用上述前缀的能力)。

【讨论】:

  • 谢谢,我在配置中添加了auto-create-jms-queues="true" auto-create-queues="true" auto-create-addresses="true"。现在我收到了消息。我并不完全清楚分隔符是/.,以及通配符是否应该是#>。我现在需要找出它实际上是在哪个主题上发布的。我通过 MQTT 获得的消息是 ActiveMQDestination 类型的,而不是主题,那么如何获得名称?
  • 如架构中所述,auto-create-jms-queues 已弃用,取而代之的是 auto-create-queuesauto-create-addresses。我不明白你在说什么通过 MQTT 收到的消息是 ActiveMQDestination 类型的。 ActiveMQDestination 类是 JMS 实现的一部分,与 MQTT 无关。这似乎是一个新的/不同的问题,可能最好在新帖子上。
  • 我现在有一个监听 TestTopic.# 的 MDB。这很好用。出于测试目的,我创建了一个调度程序,将消息发布到TestTopicTestTopic.subtopic,这很好。在消息中destination 的类型是Topic。没关系。当我通过 MQTT(例如jms/topic/TestTopic)发布相同的主题时,目标只有Destination 类型(特别是ActiveMQDestination),而不是Topic。而且由于Destination 没有名称,我如何获得主题的名称?我想避免通过反射调用 getName() 或 getAddress。
  • the JavaDoc for Destination 中所述,它没有自己的方法和 4 个子接口 - QueueTemporaryQueueTemporaryTopicTopic。无需反思即可获得名称。只需if (destination instanceof Topic) {name = ((Topic)destination).getTopicName();}
  • 这就是为什么我说,我通过 MQTT 收到的消息在其目的地既不是主题也不是队列。当我通过 JMS 在 Wildfly 中发帖时,我得到了目标 org.apache.activemq.artemis.jms.client.ActiveMQTopic - 但是当它通过 MQTT 发布时,我得到了 org.apache.activemq.artemis.jms.client.ActiveMQDestination,它没有实现它们中的任何一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多