MQTT 主题的高级特性

摘要:
当应用程序消息通过MQTT传输时,它们具有相关的服务质量和主题。主题本质上是一个字符串。MQTT协议规定主题是UTF-8编码的字符串,这意味着可以通过比较编码的UTF-8字节或解码的Unicode字符来比较主题过滤器和主题名称。主题名称和主题筛选器是UTF-8编码的字符串。除了不能超过UTF-8编码字符串的长度限制外,主题名称或主题筛选器的级别数没有其他限制。相邻主题层次结构分隔符表示零长度主题层次结构。

什么是主题
MQTT 协议通过网络传输应用消息。应用消息通过 MQTT 传输时,它们有关联的服务质量(QoS)和主题(Topic)。主题本质上是一个字符串,MQTT 协议规定主题是 UTF-8 编码的字符串,这意味着,主题过滤器和主题名的比较可以通过比较编码后的 UTF-8 字节或解码后的 Unicode 字符。

主题名和主题过滤器
主题名
附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本给每一个匹配的客户端订阅。
主题过滤器
订阅中包含的一个表达式,用于表示相关的一个或多个主题。主题过滤器可以使用通配符。
如果订阅的主题过滤器与消息的主题名匹配,应用消息会被发送给每一个匹配的客户端订阅。主题资源可以是管理员在服务端预先定义好的,也可以是服务端收到第一个订阅或使用那个主题名的应用消息时动态添加的。服务端可以使用一个安全组件有选择地授权客户端使用某个主题资源。

主题和主题过滤器命名的规则
所有的主题名和主题过滤器必须至少包含一个字符。
主题名和主题过滤器是大小写敏感的。ACCOUNTS 和 Accounts 是不同的主题名。
主题名和主题过滤器可以包含空格字符。Accounts payable 是合法的主题名
主题名或主题过滤器以前置或后置斜杠 / 区分。/finance 和 finance 是不同的。
只包含斜杠 / 的主题名或主题过滤器是合法的。
主题名和主题过滤器不能包含 null 字符(Unicode U+0000)。
主题名和主题过滤器是 UTF-8 编码字符串,除了不能超过 UTF-8 编码字符串的长度限制之外,主题名或主题过滤器的层级数量没有其它限制。
主题层级
主题层级分隔符
斜杠(“/” U+002F)用于分割主题的每个层级,为主题名提供一个分层结构。分隔符用于将结构化引入主题名。如果存在分隔符,它将主题名分割为多个主题层级,是消息主题层级设计中很重要的符号。 比方说:aaa/bbb、aaa/bbb/ccc 和 aaa/bbb/ccc/ddd 这样的消息主题格式,是一个层层递进的关系,可通过多层通配符同时匹配两者,或者单层通配符只匹配一个。 这在现实场景中,可以应用到:公司的部门层级推送、国家城市层级推送等包含层级关系的场景。

MQTT 订阅报文包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅的主题过滤器可以包含特殊的通配符,允许客户端一次订阅多个主题。当客户端订阅指定的主题过滤器包含两种通配符时,主题层级分隔符就很有用了。主题层级分隔符可以出现在主题过滤器或主题名字的任何位置。相邻的主题层次分隔符表示一个零长度的主题层级。

主题过滤器中可以使用通配符,但是主题名不能使用通配符。单层通配符和多层通配符只能用于订阅 (subscribe) 消息而不能用于发布 (publish) 消息,层级分隔符两种情况下均可使用。

多层通配符
井字符号(“#” U+0023)是用于匹配主题中任意层级的通配符。多层通配符表示它的父级和任意数量的子层级。

例如,如果客户端订阅主题 sport/tennis/player1/#,它会收到使用下列主题名发布的消息:

sport/tennis/player1
sport/tennis/player1/ranking
sport/tennis/player1/score/wimbledon
因为多层通配符包括它自己的父级,所以 sport/# 也匹配单独的 sport 主题名,sport/tennis/player1/# 也可以匹配 sport/tennis/player1。

单独的多层通配符 # 是有效的,它会收到所有的应用消息。

多层通配符必须单独指定,或者跟在主题层级分隔符后面。多层通配符必须是主题过滤器的最后一个字符。因此,sport/tennis# 和 sport/tennis/#/ranking 都是无效的多层通配符。

单层通配符
加号 (“+” U+002B) 是只能用于单个主题层级匹配的通配符。例如,sport/tennis/+ 匹配 sport/tennis/player1 和 sport/tennis/player2 ,但是不匹配 sport/tennis/player1/ranking。同时,由于单层通配符只能匹配一个层级,sport/+ 不匹配 sport 但是却匹配 sport/。

在主题过滤器的任意层级都可以使用单层通配符,包括第一个和最后一个层级,可以在主题过滤器中的多个层级中使用它,也可以和多层通配符一起使用,+、+/tennis/# 、sport/+/player1 都有有效的。在使用单层通配符时,单层通配符占据过滤器的整个层级,sport+ 是无效的。

以 $ 开头的主题
服务端不能将 $ 字符开头的主题名匹配通配符 (#或+) 开头的主题过滤器, 订阅 # 的客户端不会收到任何发布到以 $ 开头主题的消息,订阅 +/monitor/Clients 的客户端也不会收到任何发布到 $SYS/monitor/Clients 的消息。服务端应该阻止客户端使用这种主题名与其他客户端交换消息,客户端注意不能使用 $ 字符开头的主题。

服务端实现可以将 $ 开头的主题名用作其他目的。,例如 $SYS/ 被广泛用作包含服务器特定信息或控制接口的主题的前缀。订阅 $SYS/# 的客户端会收到发布到以 $SYS/ 开头主题的消息,订阅 $SYS/monitor/+ 的客户端会收到发布到 $SYS/monitor/Clients 主题的消息,如果客户端想同时接受以 $SYS/ 开头主题的消息和不以 $ 开头主题的消息,它需要同时订阅 # 和 $SYS/#。

举个例子
比如我们用传感器监视家里的卧室、客厅以及厨房的温度、湿度和空气质量,可以设计一下几个主题:

myhome/bedroom/temperature
myhome/bedroom/humidity
myhome/bedroom/airquality
myhome/livingroom/temperature
myhome/livingroom/humidity
myhome/livingroom/airquality
myhome/kitchen/temperature
myhome/kitchen/humidity
myhome/kitchen/airquality
当我们想获取卧室的所有数据时,可以订阅 myhome/bedroom/+ 主题,当我们想获取三个房间的温度数据的时候,可以订阅 myhome/+/temperature 主题,当我们想获取所有的数据的时候,可以订阅 myhome/# 或者 #。


原文链接:https://blog.csdn.net/emqx_broker/article/details/103593434

免责声明:文章转载自《MQTT 主题的高级特性》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇PHP解决跨域问题版本控制工具VSS使用介绍下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Win32编程

    Win32编程 此资料为ITjob软件开发教程网提供,特此分享,互相学习! C/C++/VC/MFC技术交流群:95453496 一、Win32编程基本概念 1、消息驱动 在介绍Windows消息驱动概念之前,我们首先来回顾面向过程的程序结构:main()程序有明显的开始、中间过程和结束点,程序是围绕这个过程编写好相关的子过程,再把这些子过程串联...

谈谈Linux下的数据流重定向和管道命令

一、标准输入、标准输出、错误输出概述 1.标准输入(stdin)是指令数据的输入,代码为0,使用<或者<<,默认是键盘。 2.标准输出(stdout)是指令执行成功返回的结果,代码为1,使用>或者>>,默认在屏幕显示。 3.标准错误输出(stderr)是指令执行失败返回的错误信息,代码为2,使用2>或者2>&...

HOOK技术的一些简单总结

好久没写博客了, 一个月一篇还是要尽量保证,今天谈下Hook技术。 在Window平台上开发任何稍微底层一点的东西,基本上都是Hook满天飞, 普通应用程序如此,安全软件更是如此, 这里简单记录一些常用的Hook技术。 SetWindowsHookEx 基本上做Windows开发都知道这个API, 它给我们提供了一个拦截系统事件和消息的机会, 并且它可...

一个消息调度框架构建

基本框架 MDU(消息分发单元):包含一个消息处理任务,包含自身的消息队列,是一个消息调度的基本单位。 PID (功能子模块) :框架中用PID作为模块的划分,每个模块具有自己的PID编号,根据功能和调度需求可以安排多个PID到一个MDU中,PID是消息通信的一个基本单位,每个PID提供一个消息处理入口。 MQ (消息队列) :使用消息队列作为任务通信...

初入spring boot(五 )websocket

一、广播式   广播式即服务端有消息时,会将消息发送给所有连接了当前endpoint的浏览器   1.配置websocket,需要在配置类上使用@EnableWebSocketMessageBroker开启websocket支持,并通过继承AbstractWebSocketMessageBrokerConfigurer类,重写其方法来配置websocket...

OpenSSL 介绍和使用

转自:https://www.jianshu.com/p/fb2ae3dc7986 一、SSL 简介 按照我的理解来解释下,为了让网络通信更安全,需要认证和加密,认证是说明你是要找的人,加密是为了让截获中间报文第三者无法得到消息内容。 为此有人设计了SSL,即套接字上的安全层,简单来说就是在TCP之上做一个安全通信层,HTTP on SSL 即是HTT...