MQTT: Topic Names and Topic Filters

Topic Names and Topic Filters

Topic wildcards


Topic Name 和 Topic Filter 的区别就是 Topic Name 不能包含通配符,而 Topic Filter 可以包含通配符。

Topic Name 标识一个具体的主题,而 Topic Filter 可以标识一个或者一组主题。


Topic level separator


主题级别分隔符 (topic level separator), 用 / 标识。

/ 用于将结构引入主题名称中。 如果出现主题级别分割符,它将一个字符串的主题名称分割为多个“主题级别”。

两个相邻的/ 标识一个长度为零的主题级别。

它的作用就像文件路径中的路径分隔符。


Multi-level wildcard


多级通配符 (multi-level wildcard), 用 # 标识。

匹配任意多级别的主题, 包括它的父层级和所有子层级。

这个通配符可以单独使用或者跟在主题级别分隔符之后, 而且它必须是当前 Topic filter 的最后一个字符。

例如:

比如一个客户端订阅了主题 "sport/tennis/player1/#", 那么下面这些主题都会被匹配上:
  - "sport/tennis/player1"
  - "sport/tennis/player1/ranking"
  - "sport/tennis/player1/score/wimbledon"
- "sport/#" 与 “sport” 主题也匹配,因为 "#" 可以匹配父层级。
- "#" 也是合法的,它匹配所有的主题。
- "sport/tennis/#" 也是合法的
- "sport/tennis#" 是非法的
- "sport/tennis/#/ranking" 是非法的

Single level wildcard


单级通配符(single level wildcard), 用 + 标识。

匹配单个级别的主题。

可以在任意级别中使用这个通配符。

但是它必须独占当前主题级别。

可以在一个topic filter 中多次使用这个通配符。

可以和多级通配符搭配使用。

例子:

"sport/tennis/+" 
匹配 "sport/tennis/player1" 和 "sport/tennis/player2", 
不匹配 "sport/tennis/player1/ranking" (因为单级通配符只能匹配一个层级,而这里在 tennis 之后有两个层级)

"sport/+" 不匹配 "sport", 但是匹配 "sport/"
- "+" 是合法的
- "+/tennis/#" 是合法的
- "sport+" 是非法的
- "sport/+/player1" 是合法的
- "/finance" 匹配 "+/+" 和 "/+", 但是不匹配 "+"

Topics beginning with $


服务器不应该将以通配符开始的 topic filter 与以 $ 开头的 topic name 进行匹配。

服务器应该阻止客户端通过这些 topic 与其他客户端交换消息。

服务器应该使用以 $ 开头的 topic 做其他用途。

比如:以 $SYS/ 开头的主题被广泛的用于提供服务器特定的信息或者控制 API

例子:

- 订阅主题 "#" 的客户端不会收到那些被发布到以$开头的 topic 中的消息。
- 订阅主题 "+/monitor/Clients" 的客户端不会收到那么些被发布到以 "$SYS/monitor/Clients" 主题中的消息。
- 订阅主题 "$SYS/#" 的客户端会收到那些被发布到以 "$SYS/" 开头的主题中的消息
- 订阅主题 "$SYS/monitor/+" 的客户端会收到那些被发布到以 "$SYS/minitor/Clients" 主题中的消息
- 如果客户端想同时收到所有以 $SYS/ 开头的和非 $ 开头的主题中的消息,那么它必须同时订阅主题 "#" 和 "$SYS/#"

Topic semantic and usage


如下规则被应用到 topic name 和 topic filter:

  • topic name 和 topic filter 的长度至少为 1.
  • topic name 和 topic filter 是大小写敏感的
  • topic name 和 topic filter 中可以包含空白字符
  • 前缀,后缀 / 标识一个不同的 topic name 或者 topic filter
  • 只包含一个 “/” 字符的 topic name 和 topic filter 是合法的
  • topic name 和 topic filter 中不能包含空字符(null character, Unicode U+0000)
  • topic name 和 topic filter 使用 UTF-8 编码,编码之后的长度不能超过 65535.
  • topic name 和 topic filter 的层级可以无限深,没有限制
  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用C++ paho mqtt库中的mqtt::topic发布json对象的示例代码: ```c++ #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <json/json.h> #include "mqtt/async_client.h" using namespace std; const string ADDRESS("tcp://localhost:1883"); const string CLIENTID("AsyncPublisher"); const string TOPIC("test"); const int QOS = 1;const int TIMEOUT = 10000L; class callback : public virtual mqtt::callback { public: virtual void connection_lost(const std::string& cause) { cout << "\nConnection lost" << endl; if (!cause.empty()) cout << "\tcause: " << cause << endl; } virtual void delivery_complete(mqtt::delivery_token_ptr token) { cout << "\n\tDelivery complete for token: " << (token ? token->get_message_id() : -1) << endl; } }; int main(int argc, char* argv[]) { mqtt::async_client client(ADDRESS, CLIENTID); mqtt::connect_options connOpts; connOpts.set_keep_alive_interval(20); connOpts.set_clean_session(true); callback cb; client.set_callback(cb); try { mqtt::token_ptr conntok = client.connect(connOpts); conntok->wait_for_completion(); Json::Value root; root["name"] = "John"; root["age"] = 25; root["email"] = "john@example.com"; string json_str = root.toStyledString(); mqtt::message_ptr pubmsg = mqtt::make_message(TOPIC, json_str); pubmsg->set_qos(QOS); mqtt::delivery_token_ptr pubtok = client.publish(pubmsg); pubtok->wait_for_completion(TIMEOUT); cout << "Message '" << json_str << "' published to topic '" << TOPIC << "'" << endl; client.disconnect()->wait_for_completion(); } catch (const mqtt::exception& exc) { cerr << exc.what() << endl; return 1; } return 0; } ``` 在这个示例中,我们使用了Jsoncpp库来创建一个Json对象,并将其转换为字符串。然后,我们使用mqtt::make_message()函数创建一个mqtt::message_ptr对象,该对象包含要发布的主题和消息。最后,我们使用mqtt::async_client类的publish()函数将消息发布到主题上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VFSSoft

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值