Qt MQTT 概述

提供对MQTT协议和Qt MQTT模块的深入了解。

Qt MQTT 使您能够创建可以通过MQ遥测传输(MQTT)协议进行通信的应用程序和设备。它完全符合MQTT协议规范。

发布和订阅

MQTT 是一种机器对机器的连接协议,它运行在发布-订阅模型上。MQTT 客户端是一个程序或设备,它使用 MQTT 创建与 MQTT 服务器(也称为 broker)的网络连接。一旦连接建立,客户端可以向 broker 发送消息。其他客户端可以订阅由该客户端发送的特定主题的通知。

../_images/mqtt.png

例如,如果客户端2订阅了主题A上的消息,当客户端1在该主题上发送消息时,它会收到通知。如果客户端3订阅了主题A主题B,它会收到关于这两个主题上消息的通知。

Qt MQTT 是一个不包含代理的客户端解决方案。它特别适合开发嵌入式设备的遥测应用程序。然而,Qt MQTT 没有外部依赖,因此实现的客户端可以在所有支持的 Qt 平台上运行。

主题

主题以分层树结构存储。标准未指定树应如何设计,也未提供预定义的层次集。您可以根据项目需求自由设计层次结构。以下是一个主题层次结构的示例,其中active表示所有活动传感器,而housegarage是单个传感器:

sensors/active
sensors/house/temperature
sensors/house/bedroom/light
sensors/house/livingroom/light
sensors/garage/temperature
sensors/garage/light

使用通配符订阅主题

当客户端订阅主题时,他们可以使用井号(#)和加号(+)作为通配符。井号表示客户端希望接收关于某个主题及其所有子主题的所有消息的通知。例如,如果客户端订阅了sensors/house/#,它将接收关于house传感器的所有消息。

加号表示在寻找匹配的子主题时可以跳过树上的一个分支。例如,如果客户端订阅了sensors/+/temperature,它将接收到关于temperature的消息,无论哪个传感器发送了它们。您可以使用多个加号来跳过多个分支。例如,house/+/+/temperature可以用来接收关于房屋中所有公寓的所有房间的温度的消息。

共享订阅

共享订阅 描述了一个主题过滤器的订阅者池。与所有订阅者都接收消息不同,只有一个订阅者会接收消息。这使得在多个客户端之间实现负载均衡成为可能。共享订阅的格式为:

$share/{sharename}/{topicfilter}

例如,如果客户端1客户端2应该共享对主题sensors/house/temperature的订阅,那么要订阅的主题过滤器是:

$share/poolAB/sensors/house/temperature

未定义服务器分发消息的顺序。这是一个服务器特定的选项。

要识别服务器是否支持共享订阅,请参见sharedSubscriptionSupported()

主题别名

将主题结构化为树形有助于分离数据通道并提供信息的逻辑顺序。然而,这可能导致在发布消息时使用非常长的主题名称,从而增加每条消息的大小。

MQTT 5.0协议版本引入了主题别名来规避这个问题。不再发送主题字符串,而是发送一个整数值。为了在客户端和服务器之间创建初始映射,主题字符串和别名都需要成为消息的一部分。之后,只使用带有空主题的ID。

这种映射可以通过使用主题别名与另一个主题字符串随时更改。请注意,这种映射不一定适用于其他连接,例如从服务器到其他客户端的连接。每个连接都需要手动创建这种映射。

Qt MQTT 提供了一种自动化的机制来帮助降低数据速率。在 QMqttClient 创建连接后,服务器支持的主题别名信息会被存储。随后,主题别名会按照消息发布的顺序使用,直到所有可用的别名都被使用。用户始终可以通过在发布过程中使用 setTopicAlias() 来修改这种映射。

QMqttClient订阅一个主题时,服务器也可以使用主题别名,这取决于客户端设置的maximumTopicAlias()值。客户端会自动映射主题别名,并透明地将包括完整主题字符串的消息转发给用户。

安全性

客户端与代理之间的连接通过内置的身份验证系统进行保护,该系统使用用户名和密码。消息在传输层使用SSL/TLS进行加密。加密MQTT消息的标准端口号是8883。

服务质量

定义了以下消息的服务质量(QoS)级别:

  • 最多一次 (0) 意味着消息根据操作系统环境的最佳努力进行传递,因此可能会发生消息丢失。例如,这种级别可以用于环境传感器数据,其中单个读数的丢失并不重要,因为下一个读数很快就会发布。

  • 至少一次 (1) 意味着消息保证会到达,但可能会出现重复。

  • Exactly once (2) 意味着消息保证只到达一次。例如,这种级别可以用于计费系统,其中重复或丢失的消息可能导致错误的费用应用。

Will 消息

一个遗嘱消息,也称为遗嘱,是从客户端发送并存储在代理位置的消息。如果客户端和代理之间的连接以意外方式中断,遗嘱消息将被转发给遗嘱主题的任何订阅者。

遗嘱消息必须在连接阶段指定。因此,在调用connectToHost()connectToHostEncrypted()之前必须设置它们。遗嘱消息具有常规消息的所有属性,以及遗嘱主题、QoS级别、保留标志和消息负载。

如果客户端通过调用disconnectFromHost()以常规方式断开与代理的连接,代理将丢弃遗嘱消息。如果需要,客户端负责在断开连接之前发送所有必需的消息。

保留消息

保留的消息存储在代理端。当未来的客户端连接时,它们将收到这些消息。一个典型的用例是将发布者的当前健康状态存储在保留的消息中。订阅者将立即收到有关状态的消息。

一个代理只能存储为指定主题发送的最后一条保留消息。如果客户端发布了一条QoS级别为零的保留消息,代理必须丢弃其主题的任何先前保留消息。代理应该存储最后一条消息,但也可能丢弃它。这取决于代理的实现。