QT学习笔记-QtMQTT官方文档翻译

为了加深理解和更好的使用QTMQTT,将官方文档翻译过来记录一下


QT MQTT模块提供了一个MQTT协议规范的标准兼容性实现,使我们开发的应用能够像遥测显示器和设备一样发布遥测数据。模块支持协议版本包括MQTT 3.1, MQTT 3.1.1,和 MQTT 5.0.

Qt MQTT 概述

发布订阅消息

MQTT客户端是一个使用MQTT与MQTT服务器(broker)建立网络连接的程序或设备。一旦连接建立,客户端可向服务器发送消息。其他客户端可向服务器订阅指定主题的消息
在这里插入图片描述
如图所示,客户端2订阅了主题A,当客户端1发布了一个该主题消息时,它会收到通知。客户端3订阅了A\B两个主题,它会收到两个主题的通知。
QT MQTT提供的是客户端解决方案不包含服务器端,使用QT MQTT可以方便的为嵌入式设备开发遥测应用,而且,本模块没有其他额外依赖,因此开发的应用可以跨平台运行。

主题

主题存储在一个层次树结构中,该标准没有指定树结构设计形式,也没有提供预定义层次集。我们可以根据需求在项目中自由的设计层级结构。下述主题层级结构例子中,active表示所有激活的传感器集,其中house和garage是独立的传感器集。

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主题可以用来收集house中所有房间的temperature消息。

共享订阅

共享订阅描述了一个主题过滤器的订阅者池。与所有订阅者都能收到消息不同的是,只有一个订阅者能收到订阅消息。共享订阅可以用来实现多客户端的负载平衡。共享订阅的格式如下:

$share/{sharename}/{topicfilter}

For example, if Client 1 and Client 2 should share a subscription to the topic sensors/house/temperature, the topic filter to subscribe to is:
例如,客户端1和客户端2应该共享主题sensors/house/temperature的订阅,该订阅的主题过滤器如下:

$share/poolAB/sensors/house/temperature

这并没有定义服务器分发数据的顺序,这是服务器的特定选项。
要确定一个服务器是否支持共享订阅可以查看QMqttServerConnectionProperties::sharedSubscriptionSupported().

主题别名

树型结构的主题可以帮助我们区分数据通道和提供信息的逻辑顺序。然而这会造成在发布信息时要使用很长的主题名字。从而造成每条信息size的增加。
MQTT 5.0协议版本引入了主题别名来规避上述问题。使用整数值来替代主题字符串的发送,创建客户端和服务器间初始映射时,主题字符串和对应别名都需要作为消息的一部分。此后只需要空主题的ID。
主题别名映射可以在任意时刻使用主题别名和另一个主题字符串进行更改。谨记此映射并不适用于其他连接,每个连接都需要手动的创建主题别名映射。
Qt MQTT提供了一种自动机制来帮助降低数据速率。使用QMqttClient创建连接之后,服务器支持的主题别名信息将被存储;随后主题别名将按序用在发布的信息中,直到所有可用的主题别名均被使用。发布过程中用户可以使用QMqttPublishProperties::setTopicAlias() 修改别名映射。
QMqttClient 订阅主题时,服务器也可使用主题别名,基于客户端设置的值QMqttConnectionProperties::maximumTopicAlias() 客户端自动映射主题别名和显式地将消息转发给用户,包括完整的主题字符串。

安全性

客户端和服务器之间的连接被内部鉴权系统使用用户名和密码保护。消息使用SSL/TLS在传输层进行编码,统一的编码MQTT消息端口号为8883.

服务质量

消息服务质量(QoS)等级定义如下:

  • QoS=0表示消息只会被发送一次,但该消息可能会丢失。
  • QoS=1表示确保消息会到达至少一次,但可能会造成订阅者收到多条重复消息。
  • QoS=2表示确保消息会到达且仅到达一次。
    三种不同的服务质量分别对应不同场景,例如远程抄表和温湿度传感器可以选择“最多一次传输”/“至少一次传输”,因为在该场景下就算丢失/重复了几份数据也不会产生太大的影响,还能降低功耗;在计费场景下一般选择“正好一次传输“,防止重复计费。

遗嘱消息

遗嘱消息又称证明消息,是由客户端发送,存储在服务器端的消息。当客户端于服务器端的连接由于异常断开时,遗嘱消息将向所有订阅遗嘱主题的订阅者发送。
遗嘱消息必须在建立连接状态时指定。因此需要在使用
QMqttClient::connectToHost()QMqttClient::connectToHostEncrypted()之前设置遗嘱消息参数,遗嘱消息和常规消息有同样的属性,遗嘱主题,QoS等级,保留标志和消息内容。
当客户端从服务器端通过使用 QMqttClient::disconnectFromHost()正常断开时,服务器端将弃置遗嘱消息。如果需要,客户端将在断开连接前发送所有需要的消息。

保留消息

保留消息存储在服务器端,当未来客户端再次连接时,将会收到这些消息。一个典型用例是在保留消息中存储发布者的当前心跳状态,订阅者立刻收到该状态信息。
A broker can only store the last retained message sent for a specified topic. If a client publishes a retained message with the QoS level zero, any previously retained message for its topic at the broker must be discarded. The broker should store the last message, but may also discard it. This depends on the implementation of the broker.
一个服务器端仅存储指定主题最近一条保留消息。如果一个客户端发布了QoS0等级的保留消息,该主题下任何先前存储在服务器端的保留消息必须弃置。服务器端应该存储最新消息,但是也可弃置它。这取决于服务器端的实现。

Qt MQTT 示例

建立客户端

1.建立连接
首先,使用QMqttClient类建立一个MQTT客户端,该类提供了对应属性来设置唯一客户端ID和服务器端域名/ip和端口

m_client = new QMqttClient(this);
m_client->setHostname(ui->lineEditHost->text());
m_client->setPort(ui->spinBoxPort->value());

我们没有设置客户端ID,因此会自动生成一个。
2.处理接收到的消息
接下来我们要创建一个槽函数响应QMqttClient::messageReceived() 信号来接收服务器端下发的消息,我们将接收到的消息显示在界面上。

    connect(m_client, &QMqttClient::messageReceived, this, [this](const QByteArray &message, const QMqttTopicName &topic) {
        const QString content = QDateTime::currentDateTime().toString()
                    + QLatin1String(" Received Topic: ")
                    + topic.name()
                    + QLatin1String(" Message: ")
                    + message
                    + QLatin1Char('\n');
        ui->editLog->insertPlainText(content);
    });

3.订阅主题
调用QMqttClient::subscribe() 来订阅主题:

void MainWindow::on_buttonSubscribe_clicked()
{
    auto subscription = m_client->subscribe(ui->lineEditTopic->text());
    if (!subscription) {
        QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not subscribe. Is there a valid connection?"));
        return;
    }
}

我们使用QMqttSubscription来保存订阅的属性,主题,状态,QoS等级。
订阅和消息的QoS等级可以分开设置。订阅的QoS等级决定了最小QoS等级。如果发送的消息设置了更高等级,则服务器提高此消息到高等级。例如,客户端A订阅了一个QoS1等级的主题,客户端B向该主题发布了一个QoS0的消息,服务器会自动将此消息QoS等级提高到1;如果客户端B发布的是QoS2的消息,则服务器将发送QoS2的消息给订阅者客户端A。
4.发布主题
调用QMqttClient::publish() 来发布主题:

void MainWindow::on_buttonPublish_clicked()
{
    if (m_client->publish(ui->lineEditTopic->text(), ui->lineEditMessage->text().toUtf8()) == -1)
        QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));
}

Qt MQTT C++类

命名空间

项目Value
QMqtt包含了在整个模块中使用的各种各样的标识符

类名作用
QMqttAuthenticationProperties认证过程中的配置选项
QMqttClient与MQTT服务器通信的主要接口
QMqttConnectionProperties表示一个QMqttClient对象调用 QMqttClient::connectToHost()时传递给服务器的配置参数
QMqttLastWillProperties表示当在连接服务器过程中指定最后遗嘱消息时一个QMqttClient能够传递给服务器的配置选项
QMqttMessage从服务器获得的订阅消息的信息
QMqttMessageStatusProperties服务器在分发消息时提供的附加信息
QMqttPublishProperties收发消息时的配置选项
QMqttServerConnectionProperties客户端要连接的服务器配置信息
QMqttStringPairMQTT 5.0 标准的字符串数据对类型
QMqttSubscription特定主题下从服务器接收到的订阅消息
QMqttSubscriptionPropertiesQMqttClient向一个主题过滤器订阅时传递的配置信息
QMqttTopicFilterMQTT 主题过滤器
QMqttTopicNameMQTT 主题名字
QMqttUnsubscriptionPropertiesQMqttClient向一个主题过滤器取消订阅时传递的配置信息
QMqttUserProperties可传递给服务器的QMqttStringPair 值列表
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值