MQTT消息传递与接收
MQTT客户端发布消息时使用的是PUBLISH报文,发布成功之后会接收到PUBACK报文。
订阅时发送SUBSCRIBE报文,订阅成功会接收到SUBACK报文。
取消订阅发送UNSUBSCIBE报文。
PUBLISH
在MQTT中,客户端在成功连接到代理之后就可以发送消息。
代理根据主题来对消息进行过滤并转发到已订阅的客户端,每条消息都会包含一个主题。
消息的有效负载是以字节为单位的数据,支持各种数据类型,包括文本、数字、图像、二进制数据以及XML或JSON。
PUBLISH报文有以下几个属性,分别是:
PacketID
数据包标识符(PackageID),在MQTT代理和客户端之间唯一标识消息。用于识别特定消息并确保消息按发送顺序传递,仅在QoS>0时有效。
可以使用MQTT客户端库或代理来设置此标识符。
当在QoS>0的消息通信过程中,客户端必须等待来自代理的PUBACK或PUBREC消息,然后才能发送下一条新消息。而PackageID就是用来区分是否是新消息。
PacakgeID对于MQTT的可靠性机制至关重要,有助于确保消息正确有效地传递。
Topic Name
用于指示该条消息发布到哪个主题上,MQTT代理向订阅该主题的客户端传递这条消息。
主题是一个字符串,使用“/”作为分隔符用以分层,为客户端提供订阅消息的方式。
订阅主题可以使用以下两种通配符:
+
:用于匹配主题层次结构中的单个级别。例如,订阅sensors/+/livingroom
将匹配sensors/temperature/livingroom
和sensors/humidity/livingroom
,但不匹配sensors/temperature/kitchen
。#
:用于匹配层次结构中的多个级别。例如,订阅sensors/#
将匹配sensors/temperature/livingroom
、sensors/humidity/kitchen
和sensors/power/meter1
。
QoS
消息质量等级,QoS有3个等级,分别是:
QoS等级 | 说明 |
---|---|
QoS0(最多一次) | 此级别不保证消息传递成功。发送方仅传递一次消息,无论接收方是否收到,都不在重发。 |
QoS1(至少一次) | 此级别确保消息至少传递一次。发送方在收到接收方的确认之前会一直传递消息,可能会导致多次传递。 |
QoS2(确定一次) | 此级别为消息传递提供最高级别的保证,确保消息恰好传递一次。发送方在收到接收方的确认之前发送的消息都被认定是重复消息,直到收发双方协商一致之后开启新消息传递。 |
QoS2比QoS1级别多了一个步骤,收发双方需要相互确认下一条新消息的开始。
Retain Flag
保留标志(Retain)决定是否将消息存储在代理中。
当Retain标志设置1时,无论该消息对应的主题是否被客户端订阅,代理都会存储该消息与对应的主题。
发布消息时,保留标志设置为1的消息称为保留消息,MQTT代理为每个主题仅保留一条消息。
当新客户端订阅带有保留消息的主题时,代理会将最新的保留消息(关于该主题)发送给客户端。这将允许客户接收最新的相关信息,即使其以前没有订阅过该主题。
Payload
负载是消息的实际内容,可以包含任何类型的数据。
MQTT可以处理不同的数据类型,包括图像、任何编码的文本、加密数据和二进制数据。
DUP Flag
该标志表示消息是重复的,仅与QoS>0的消息相关。
通常在接收者(客户端或代理)没有发送确认消息的情况下再次发送该消息时设置。
当客户端或代理收到带有DUP标志的消息时,如果之前已经收到具有相同PacketID的消息,则会忽略该消息。如果客户端或代理之前未收到相同PacketID的消息,则正常处理该消息。
MQTT代理如何处理消息
当MQTT代理接收到客户端传递的消息后,为了确保按照客户端指定的QoS级别处理消息,会执行以下步骤:
- 消息接收:MQTT代理接收客户端发送的消息,并验证报文头和内容格式。
- 消息确认:MQTT代理根据客户端指定的QoS级别,向客户端发送确认消息。
- 处理消息:MQTT代理根据客户端发送的消息主题,将该消息传递给订阅了该主题的客户端。并且根据消息的Retain标志,判断是否需要存储在代理中。
发布消息的客户端只关心将PUBLISH消息传递给代理。
一旦代理接收到PUBLISH消息,就有责任将该消息传递给所有订阅者。
发布客户端不会获得任何反馈,以了解是否有人对发布的消息感兴趣,或者有多少客户端收到了来自代理的消息
SUBSCRIBE
收发消息是相辅相成的,如果没有订阅者接收消息,那么发布消息就毫无意义。
当客户端想要订阅消息,就需要向代理发送SUBSCRIBE报文,以告知代理订阅的主题。
SUBSCRIBE报文包含两个字段,分别是数据包标识符(PackageID)和订阅主题列表。
字段名 | 说明 |
---|---|
PacketID | MQTT代理和客户端之间唯一标识消息,可以使用客户端库或代理进行设置。用于确保客户端识别出与SUBSCRIBE相关联的响应消息。 |
Topic List | 客户端想要订阅的一个或多个主题的列表。列表中每条都会包含一个主题和一个QoS级别。 |
订阅的主题可以包含通配符,
如果一个客户端多次订阅相同主题,MQTT代理仅为该主题提供最高级别的QoS。
当MQTT代理收到来自客户端的带有主题与QoS级别的SUBSCRIBE报文时,将会返回一条带有QoS最大级别的SUBACK报文通知客户端订阅是否成功。
SUBACK
当MQTT客户端向代理发送一条带有主题和QoS级别的SUBSCRIBE报文时,代理就会向客户端响应一条SUBACK报文来确认该订阅请求。
SUBACK报文用于MQTT代理确认收到SUBSCRIBE报文,并指示是否接受或拒绝该订阅请求。
交互流程如下图:
SUBACK包含以下两个字段:数据包标识符(PacketID)和返回代码列表。
字段名 | 说明 |
---|---|
PacketID | 用于客户端识别出该响应消息与哪条SUBSCRIBE报文相关联 |
Return Code | 用于客户端判断是否订阅成功。返回码的个数与SUBSCRIBE报文中的订阅主题一一对应。取值结果如下表所示: |
返回码是二进制数值,表示MQTT代理支持订阅主题的QoS级别。
返回码的取值 | 说明 |
---|---|
0 | 表示代理在该主题上允许的QoS最大级别为0,亦即最多一次。 |
1 | 表示代理在该主题上允许的QoS最大级别为1,亦即至少一次。 |
2 | 表示代理在该主题上允许的QoS最大级别为2,亦即刚好一次。 |
128 | 表示代理不接受订阅。失败的原因可能是客户端没有足够的权限订阅主题、主题格式不正确或其他原因。 |
UNSUBSCRIBE
在MQTT中,当客户端需要取消订阅主题时,可以向代理发送一条UNSUBSCRIBE报文。
与SUBSCRIBE报文类似,拥有两个字段数据包标识符与待取消订阅的主题列表。
字段名 | 说明 |
---|---|
PacketID | 用于确保客户端识别出与UNSUBSCRIBE相关联的相应消息。 |
Topic List | 客户端想要取消订阅的一个或多个主题的列表。 |
UNSUBACK
当MQTT接收到客户端发送的UNSUBSCRIBE报文后,会响应一条UNSUBACK确认报文,用于通知客户端该订阅已经被删除。
UNSUBACK报文包含了两个字段,分别是数据包标识符(PacketID)与返回码(Return Code)。
交互流程如下图:
字段名 | 说明 |
---|---|
PacketID | 用于客户端识别出该响应消息与哪条UNSUBSCRIBE相关联 |
Return Code | 用于客户端判断是否取消订阅成功。0表示成功取消订阅,17表示由于无效或格式不正确的主题而取消失败。 |
当MQTT客户端接收到代理发送的UNSUBACK报文之后,客户端就可以已经删除UNSUBSCRIBE报文中取消订阅的主题。
- 原文作者:生如夏花
- 原文链接:https://blduan.top/post/%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE/mqtt/mqtt%E6%B6%88%E6%81%AF%E4%BC%A0%E9%80%92%E4%B8%8E%E6%8E%A5%E6%94%B6/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。