什么是 MQTT 发布消息?
在 MQTT 中,客户端连接到代理后可以立即发布消息。消息根据主题进行过滤,每条消息必须包含一个主题,代理可以使用该主题将消息转发给感兴趣的客户端。每条消息的有效负载包括以字节格式传输的数据,发送客户端可以选择发送任何类型的数据,包括文本、数字、图像、二进制数据,甚至成熟的 XML 或 JSON。
MQTT 负载格式示例
MQTT 与数据无关,这意味着可以根据客户端的特定用例构建有效负载。有效负载是消息的主要内容,是客户端订阅、接收和处理的内容。
MQTT 中的 PUBLISH 消息具有确定其行为的多个属性,包括数据包标识符、主题名称、服务质量、保留标志、有效负载和 DUP 标志。让我们分别看一下。
什么是 MQTT PacketId 或数据包标识符?
数据包标识符(PacketId)是 MQTT 中的一个基本属性。它用于识别特定消息并确保消息按发送顺序传递,特别是在使用大于零的 QoS 级别时。数据包 ID 由客户端分配,并包含在 PUBLISH、PUBREL、PUBREC 和 PUBCOMP 消息中。当代理收到 PUBLISH 消息时,它会为该消息分配一个数据包 ID,并向客户端发送包含 PUBLISH 消息的数据包 ID 的 PUBACK 消息。客户端使用 PUBACK 消息来确认代理已收到消息。
在 MQTT 协议中,与消息发布和确认相关的消息分为几个阶段:
1.发布 (PUBLISH):这是该过程的第一阶段,涉及 MQTT 客户端向代理发布消息。该消息包含主题和负载。
2.发布接收(PUBREC):broker收到PUBLISH消息后,发送PUBREC消息以确认已收到该消息。这是该过程的第二阶段。
3.发布发布(PUBREL):客户端收到 PUBREC 消息后,会发送 PUBREL 消息以释放代理将消息保留在内存中的责任。这是第三阶段。
4.发布完成(PUBCOMP):代理最终发送 PUBCOMP 消息以确认已成功接收并处理该消息。这是该过程的第四个也是最后一个阶段。
这四个消息是 MQTT 协议的服务质量 (QoS) 机制的一部分,可确保可靠的消息传递。QoS 级别决定客户端和代理之间交换的消息数量。
值得注意的是,当消息在客户端和代理之间流动时,数据包标识符唯一地标识消息。数据包标识符仅与大于零的 QoS 级别相关。这不仅适用于 PUBLISH,也适用于 SUBSCRIBE、UNSUBSCRIBE 和 CONNECT 消息。
客户端库和/或代理负责设置此内部 MQTT 标识符。当使用大于零的 QoS 级别时,客户端必须等待来自代理的 PUBACK 或 PUBREC 消息,然后才能发送下一条消息。客户端还应该跟踪它已发送和接收的数据包 ID,以确保消息不会丢失或重复。总体而言,数据包 ID 对于 MQTT 的可靠性机制至关重要,有助于确保消息正确高效地传递。
MQTT 主题名称是什么?
MQTT 使用主题名称作为基本概念。它使用正斜杠作为分隔符分层构造该名称,并创建一个简单的字符串。它类似于 URL 路径,但没有协议和域组件。MQTT 主题用于标记消息并为客户端提供订阅特定消息的方式。
例如,测量温度的设备可能会将其读数发布到主题"sensors/temperature/livingroom"
。对这些读物感兴趣的客户可以订阅该主题并在发布时接收更新。
MQTT 提供两种类型的通配符用于主题订阅:
- “+”(加号)用于匹配层次结构中的单个级别。例如,订阅将
"sensors/+/livingroom"
匹配“传感器/温度/客厅”和“传感器/湿度/客厅”,但不匹配“传感器/温度/厨房”。 - “#”(井号)用于匹配层次结构中的多个级别。例如,订阅“sensors/#”将匹配“sensors/温度/livingroom”、“sensors/humidity/kitchen”和“sensors/power/meter1”。
订阅大量主题会对代理性能产生重大影响。这是因为发布到客户端订阅的主题的每条消息都必须传递到该客户端。如果许多客户订阅许多主题,这很快就会成为经纪人的沉重负担。
使用通配符通过单个订阅来订阅多个主题也会影响性能。当客户端使用通配符订阅主题时,代理必须评估发布到匹配主题的每条消息,并确定是否将其转发给客户端。如果匹配主题的数量很大,这可能会导致代理的资源紧张。
为了避免性能问题,有效使用主题订阅非常重要。一种方法是尽可能使用更具体的主题过滤器,而不是依赖通配符。另一种方法是使用共享订阅,它允许多个客户端共享对某个主题的单个订阅。这可以帮助减少代理必须处理的订阅和消息的数量。最后,监控代理的性能并根据需要调整其配置对于确保最佳性能非常重要。
MQTT 中的服务质量 (QoS) 是什么?
我们在介绍 MQTT 协议一文中谈到了 MQTT 消息的服务质量级别 (QoS) 。回顾一下,QoS 由 0 到 2 范围内的数字表示。每个级别都为消息传递提供不同级别的可靠性和保证。
- QoS 0(最多一次):此级别不保证消息将被传递。消息发送一次,如果丢失或收件人未收到,则不会重发。
- QoS 1(至少一次):此级别确保消息至少传递一次,但在网络问题或故障的情况下可能会传递多次。
- QoS 2(恰好一次):此级别为消息传递提供最高级别的保证。保证消息恰好传递一次,但此级别需要发送者和接收者之间进行更多通信,这可能会增加延迟和网络流量。
选择适当的 QoS 级别取决于具体的用例。例如,QoS 0 可能适用于非关键数据,而 QoS 2 可能适用于需要高可靠性级别的关键数据。
请务必注意,QoS 级别会影响代理和网络的性能,因此建议针对特定用例使用适当的级别。有关更多信息,请阅读我们的文章MQTT 服务质量 (QoS) 0,1, & 2或其他资源,例如MQTT 5 Essentials。
什么是 MQTT 保留标志?
保留标志是一项重要功能,它确定代理是否将消息保存为指定主题的最后一个已知正确值。当retained标志设置为true时,无论是否有任何订阅的客户端,代理都会保存与指定主题匹配的最新消息。
当新客户端订阅带有保留消息的主题时,代理会将最后保留的消息(关于该主题)发送给客户端。这允许客户接收最新的相关信息,即使他们以前没有订阅过该主题。
需要注意的是,与许多其他元素一样,保留消息的使用也会影响代理的性能,尤其是在存在许多保留消息的情况下。此外,如果保留的消息频繁更新,可能会导致网络流量增加,并可能影响网络性能。
什么是 MQTT 有效负载?
有效负载是消息的实际内容,可以包含任何类型的数据。MQTT 与数据无关,这意味着它可以处理不同的数据类型,包括图像、任何编码的文本、加密数据和二进制数据。但是,请务必注意,有效负载大小可能会影响客户端和代理上的网络性能和内存使用情况。因此,建议保持有效负载尽可能小,尤其是在高频率发布消息时。
什么是 MQTT DUP 标志?
MQTT DUP 标志表示消息是重复的,并且由于预期接收者(客户端或代理)未确认原始消息而已重新发送。它仅与 QoS 大于 0 的消息相关。当客户端或代理收到设置了 DUP 标志的消息时,如果它已经收到具有相同消息 ID 的消息,则应忽略该消息。如果客户端或代理之前未收到消息,则应正常处理该消息。
MQTT 协议(MQTT 客户端库或代理)自动处理重新发送和重复机制,但需要注意的是,这可能会影响网络性能并增加网络流量。
MQTT 代理如何处理来自客户端的消息?
当客户端向 MQTT 代理发布消息时,代理会执行多项任务以确保根据客户端指定的 QoS 级别传递消息。发生的情况如下:
- 消息接收:broker读取客户端发送的消息并验证其语法和格式。
- 确认:代理向客户端发送确认消息以确认收到消息。确认级别取决于客户端请求的 QoS 级别。
- 处理:代理确定哪些客户端订阅了消息的主题,并向每个客户端发送消息的副本。代理还可以将消息保留为该主题的最后一个已知的正确值,具体取决于 Retained 标志的值。
- 反馈:发布客户端收到来自代理的确认消息,表明消息已成功发布。但是,客户端不会收到有关有多少订阅者收到该消息或是否有人对此感兴趣的反馈。
MQTT 发布的工作原理
最初发布消息的客户端只关心将 PUBLISH 消息传递给代理。一旦代理收到 PUBLISH 消息,代理就有责任将该消息传递给所有订阅者。发布客户端不会获得任何关于是否有人对已发布消息感兴趣或有多少客户端从代理收到消息的反馈。
如何订阅MQTT主题?
如果没有人收到消息,那么发布消息就没有意义。这就是订阅发挥作用的地方。一旦客户端向 MQTT 代理发布消息,该消息就必须传递给感兴趣的客户端。想要接收有关感兴趣主题的消息的客户端向代理发送一条SUBSCRIBE消息。SUBSCRIBE 消息很简单,包含唯一的数据包标识符和订阅列表。
MQTT 订阅数据包示例
数据包标识符:数据包标识符是唯一的,用于标识客户端和代理之间传输的消息。客户端库或代理负责设置此内部 MQTT 标识符。
订阅列表:一条 SUBSCRIBE 消息可以包含一个客户端的多个订阅。每个订阅都包含一个主题和一个 QoS 级别。SUBSCRIBE 消息中的主题可以包含通配符,从而可以订阅主题模式而不是特定主题。如果一个客户端存在重叠订阅,则代理会传递该主题具有最高 QoS 级别的消息。
总体而言,MQTT 允许客户端订阅特定主题、接收发布到这些主题的消息,并根据其特定用例处理有效负载。SUBSCRIBE 消息中的数据包标识符和 QoS 级别可确保消息以适当的质量级别可靠地传送。
一旦客户端向 MQTT 代理发送包含所需主题列表和 QoS 级别的 SUBSCRIBE 消息,代理就会使用 SUBACK 消息进行响应,该消息确认订阅并指示代理将提供的最大 QoS 级别。让我们更深入地了解 SUBACK。
什么是 MQTT Subback?
一旦客户端向代理发送包含主题和相应 QoS 级别的 SUBSCRIBE 消息,代理就会通过向客户端发送SUBACK消息来确认订阅请求。SUBACK 消息确认 SUBSCRIBE 消息的接收,并指示代理是否已接受或拒绝每个订阅。
MQTT SUBACK 数据包示例
数据包标识符:SUBACK 消息包含与客户端在 SUBSCRIBE 消息中包含的相同的数据包标识符,这使得客户端能够将确认与原始请求进行匹配。
返回代码:SUBACK 消息还包括针对 SUBSCRIBE 消息中指定的每个主题/QoS 对的一个返回代码。返回代码是二进制值,指示代理是否已批准或拒绝每个主题的订阅请求。
QoS级别的返回码如下:
- QoS 0:这意味着订阅请求已在 QoS 0 下获得批准。代理会在消息可用时立即将消息传递给客户端,并且没有质量保证。
- QoS 1:这意味着订阅请求已在 QoS 1 上获得批准。代理至少传递消息一次,这意味着代理向客户端至少发送一次消息。客户端收到消息后向代理发送回 PUBACK 消息,作为确认。
- QoS 2:这意味着订阅请求已在 QoS 2 上获得批准。代理只传送消息一次,这意味着代理保证消息向客户端传送一次且仅传送一次。客户端收到消息后将 PUBREC 消息发送回代理,作为确认。Broker收到PUBREC消息后向Client发送PUBREL消息,Client收到PUBREL消息后向Broker发送PUBCOMP消息。
如果代理拒绝 SUBSCRIBE 消息中的任何订阅,则 SUBACK 消息将包含该特定主题的失败返回代码。失败的原因可能是客户端没有足够的权限订阅主题、主题格式错误或其他原因。
失败返回码用0x80表示,表示经纪商不接受订阅。如果客户端没有足够的权限来订阅该主题、主题格式错误或者订阅请求存在其他问题,则可能会发生这种情况。当客户端收到失败返回代码时,它应该使用不同的主题或 QoS 级别重试订阅,或者采取适当的操作来解决订阅请求的问题。
返回码 | 返回码响应 |
---|---|
0 | 成功 - 最大 QoS 0 |
1 | 成功 - 最大 QoS 1 |
2 | 成功 - 最大 QoS 2 |
128 | 失败 |
MQTT SUBSCRIBE、SUBACK 和 PUBLISH 的工作原理
SUBACK 消息是从代理到客户端的确认消息,用于确认已授予或拒绝的订阅。数据包标识符使客户端能够将确认与原始请求相匹配,而返回代码则指示代理授予订阅的 QoS 级别。
当客户端订阅了感兴趣的主题并收到发布到这些主题的消息后,它最终可能需要取消订阅。现在让我们探讨一下 SUBSCRIBE 消息的对应部分、UNSUBSCRIBE 消息以及确认取消订阅的相应 UNSUBACK 消息。
如何使用MQTT中的取消订阅来撤销订阅?
在 MQTT 中,客户端可以通过向代理发送UNSUBSCRIBE消息来取消订阅他们已订阅的主题。与 SUBSCRIBE 类似,此消息包含用于唯一标识它的数据包标识符以及要取消订阅的主题列表。
MQTT 取消订阅数据包示例
数据包标识符:与 SUBSCRIBE 消息类似,UNSUBSCRIBE 消息中的数据包标识符用作客户端和代理之间消息流的内部 MQTT 标识符。它确保客户端和代理可以跟踪消息及其相应的确认消息。
主题列表:UNSUBSCRIBE消息中的主题列表可以包含一个或多个客户端想要取消订阅的主题。无需指定 QoS 级别,因为无论最初订阅的主题是什么,代理都会取消订阅该主题。
什么是 MQTT Unsubback?
收到 UNSUBSCRIBE 消息后,代理会发送UNSUBACK确认消息以确认删除客户端的订阅。该消息包括 UNSUBSCRIBE 消息的数据包标识符,并用作代理已成功从客户端的订阅列表中删除主题的确认。
MQTT UNSUBACK 数据包示例
数据包标识符:UNSUBACK消息中的数据包标识符与相应的UNSUBSCRIBE消息中的数据包标识符相同。这确保客户端可以识别确认消息并将其与原始取消订阅消息相关联。
返回代码:UNSUBACK 消息包含已取消订阅的每个主题/QoS 对的返回代码列表。返回代码 0 表示删除成功,而返回代码 17 表示由于主题无效或格式错误而导致删除不成功。还可以为不同的错误场景指定其他返回码。
MQTT UNSUBACK 的工作原理
在收到来自代理的 UNSUBACK 消息后,客户端可以认为 UNSUBSCRIBE 消息中的订阅已被删除。
这些详细信息可让您全面了解客户端如何取消订阅主题以及代理如何分别通过 UNSUBSCRIBE 和 UNSUBACK 消息确认删除这些订阅。
结论
MQTT 提供了一种灵活且与数据无关的方法来在客户端和代理之间发布消息。通过使用主题来过滤消息,客户可以快速轻松地订阅他们感兴趣的内容。每条消息的有效负载都可以定制,以满足每个客户端的特定需求,并且 MQTT 对各种数据类型的支持使其成为适用于许多用例的多功能解决方案。此外,了解 PUBLISH 消息的属性(例如 QoS 级别和保留标志)可以帮助客户端和代理确保消息高效可靠地传递。
回复