Skip to content

ThingsBoard 如何自定义 MQTT Topic ​

正文与配图来自原稿。业务设备已定好协议与 Topic,希望仍走 ThingsBoard MQTT 接入时的改法(以 Wiota 相关 Topic 为例)。

1、背景 ​

业务侧 MQTT 设备的协议和 Topic 都已定好,想直接用 TB 的 MQTT 接入,但设备 Topic 与 TB 默认规定不一致,该如何解决?

2、要求 ​

设备 Topic 规则示意:

设备 Topic 要求

其中:

  • 遥测 / 属性 的发布主题:一般可通过 TB 设备配置(Device Profile) 自定义,相对好办。
  • 难点往往在 RPC 相关 Topic(尤其设备订阅的下行主题)如何对齐。

3、解决问题 ​

3.1、分析源码 ​

从 TB MQTT 源码看消息进入后的处理:

MQTT 入口分析 1

MQTT 入口分析 2

MQTT 入口分析 3

关键在于如何处理设备的订阅消息:

处理订阅

源码里定义了大量 Topic,并做匹配判断。对照 TB 自带的 RPC 订阅 Topic(如 DEVICE_RPC_REQUESTS_SUB_TOPIC)即可知道自定义时该怎么挂,见下文 3.4。

MQTT 传输整体结构也可参考:MQTT Transport 源码分析。

3.2、增加 MqttTopics ​

在 MqttTopics 类中增加自己的 Topic 常量,例如:

增加 MqttTopics

java
// wiota 订阅 topic
public static final String WIOTA_RPC_RESPONSE_SUB_TOPIC_ONE = "xky/down/+";
public static final String WIOTA_RPC_RESPONSE_SUB_TOPIC_TWO = "xky/down/sgw/+";
public static final String WIOTA_RPC_RESPONSE_SUB_TOPIC_THREE = "xky/down/sgw/+/+";

(具体字符串按你设备协议替换。)

3.3、增加 TopicType ​

在 TopicType 枚举中依样增加项,把「属性响应前缀 / 属性 Topic / RPC 订阅 Topic / RPC 响应 Topic」等绑到一起:

增加 TopicType

java
WIOTA_ONE(
  MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX,
  MqttTopics.DEVICE_ATTRIBUTES_TOPIC,
  MqttTopics.WIOTA_RPC_RESPONSE_SUB_TOPIC_ONE,
  MqttTopics.DEVICE_RPC_RESPONSE_TOPIC
),
WIOTA_TWO(
  MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX,
  MqttTopics.DEVICE_ATTRIBUTES_TOPIC,
  MqttTopics.WIOTA_RPC_RESPONSE_SUB_TOPIC_TWO,
  MqttTopics.DEVICE_RPC_RESPONSE_TOPIC
),
WIOTA_THREE(
  MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX,
  MqttTopics.DEVICE_ATTRIBUTES_TOPIC,
  MqttTopics.WIOTA_RPC_RESPONSE_SUB_TOPIC_THREE,
  MqttTopics.DEVICE_RPC_RESPONSE_TOPIC
),

(构造参数顺序以你分支中 TopicType 现有枚举为准,对照默认项抄结构即可。)

3.4、增加订阅主题分支 ​

在 processSubscribe(处理 MQTT SUBSCRIBE 的逻辑)里增加对自定义 Topic 的 case 判断:

processSubscribe 位置

自定义判断示意——这样下行 RPC 就可以走自己的 Topic:

自定义订阅 case

java
// 自定义 wiota 订阅的 topic
case MqttTopics.WIOTA_RPC_RESPONSE_SUB_TOPIC_ONE: {
  processRpcSubscribe(grantedQoSList, topic, reqQoS, TopicType.WIOTA_ONE);
  activityReported = true;
  break;
}
case MqttTopics.WIOTA_RPC_RESPONSE_SUB_TOPIC_TWO: {
  processRpcSubscribe(grantedQoSList, topic, reqQoS, TopicType.WIOTA_TWO);
  activityReported = true;
  break;
}
case MqttTopics.WIOTA_RPC_RESPONSE_SUB_TOPIC_THREE: {
  processRpcSubscribe(grantedQoSList, topic, reqQoS, TopicType.WIOTA_THREE);
  activityReported = true;
  break;
}

4、测试 ​

改完重新编译 / 部署 MQTT Transport(或单体)后,用设备或 MQTT 客户端按自定义 Topic 订阅,再从平台下发 RPC,确认能收到:

测试 1

测试 2


补充(辅) ​

能力是否改源码
遥测 / 属性 发布 Topic优先 Device Profile 自定义,尽量不改源码
RPC 订阅 Topic 与默认不一致通常要改 MqttTopics + TopicType + processSubscribe(本篇)
通配符+ / # 层级需与设备真实订阅字符串及 filter 匹配方式一致

升级 ThingsBoard 大版本时,这些改动需要重新合并,建议单独分支维护。

相关文章 ​