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

主题

客户端订阅主题时,可以使用散列标记 (#) 和加号 (+) 作为通配符。哈希标记表示客户端希望接收主题及其子主题的所有消息通知。例如,如果客户端订阅了sensors/house/#,则会收到有关房屋传感器的所有消息。

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

Qos

为报文定义了以下服务质量(QoS)级别:

  • *最多一次 (0)*表示根据运行环境的最大努力传送报文,因此可能会发生报文丢失。这一级别可用于环境传感器数据等,在这种情况下,单个读数丢失并不重要,因为下一个读数很快就会发布。
  • *至少一次 (1)*表示信息一定会到达,但可能会出现重复。
  • *精确一次 (2)*表示确保信息精确到达一次。这一级别可用于计费系统等,因为重复或丢失的信息可能导致错误收费。

目前主要实现qt的mqtt客户端,订阅发布事先部署的broker,及验证

部署mqtt的broker

这方面网上有很多资料了,我采用的是EMQX的开源服务器方案,直接doker部署即可,官网emqx.com。

或者采用其公共服务器。这样本地就开启了MQTT服务,这里有两个重要的端口号要记住:1883(暴露给外部的MQTT服务端口),18083(服务器控制面板端口)。在本地浏览器输入http://127.0.0.1:18083/,打开服务器控制面板。输入初始用户名admin和用户密码public(该密码初次登录要求修改),即可进入控制面板,并进行MQTT服务器相关配置。

image-20260107195637509

验证broker

同样下载mqttx,这个开源客户端https://mqttx.app/zh,连接broker

这里的Name和Client ID随意,Host填写我们本地配置的MQTT服务器地址127.0.0.1,端口号填1883。点击Connect即可连接到本地。

img

连接后,点击New Subscription创建topic,然后就可以在该topic下收发消息。

QtMqtt的简单客户端编写

编译官方mqtt库

当前使用qt版本为6.9.3,发现扩展工具里面没有mqtt的库可以下载,查阅资料发现只有企业版本才会内置该库,其他版本需要自行下载源码编译。源码地址

https://github.com/qt/qtmqtt/

左上角分支选择和自己qt版本匹配的分支,下载。

解压后在qt打开项目(仅需打开最外层cmakelist即可),选择编译套件,img

我选的是msvc的套件,其中debug和release我都选了,分两次编译即可。

拷贝文件目录

将编译得到的文件夹build里面的debug和release的

  1. include文件夹下Qtmqtt文件夹拷贝到自己qt安装目录的include下,这是源码。只用拷贝一次
  2. bin文件夹下.dll和pdb,拷贝到qt安装目录的bin下,debug和realease都要拷贝
  3. lib文件夹下.lib和prl,拷贝到qt安装目录的lib下,debug和realease都要拷贝
  4. lib下其中cmake文件夹拷入,就可以使用find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Mqtt)找到mqtt模块
  5. 拷贝编译目录\mkspecs\modules下 所以文件到qt安装目录msvc_64\mkspecs\modules
  6. 拷贝完后测试,有可能你拷贝过去的qt6mqtttargets.cmake里面指向编译前的目录导致运行程序自动退出没有任何反馈,需要进行如下修改,从原先指向替换为qt安装目录路径。

img

将所有硬编码路径替换为 Qt 安装目录的路径:

  • 头文件路径修正cmake
1
INTERFACE_INCLUDE_DIRECTORIES "C:/Qt/6.9.3/msvc2022_64/include;C:/Qt/6.9.3/msvc2022_64/include/QtMqtt"
  • Debug 库路径修正cmake
1
2
IMPORTED_IMPLIB_DEBUG "C:/Qt/6.9.3/msvc2022_64/lib/Qt6Mqttd.lib"
IMPORTED_LOCATION_DEBUG "C:/Qt/6.9.3/msvc2022_64/bin/Qt6Mqttd.dll"
  • Release 库路径修正cmake
1
2
IMPORTED_IMPLIB_RELWITHDEBINFO "C:/Qt/6.9.3/msvc2022_64/lib/Qt6Mqtt.lib"
IMPORTED_LOCATION_RELWITHDEBINFO "C:/Qt/6.9.3/msvc2022_64/bin/Qt6Mqtt.dll"
  • INTERFACE_SOURCES 路径修正(若存在):若 Qt 安装目录下有meta_types/qt6mqtt_metatypes.json,替换路径;若无,可删除该行(不影响基础功能)。

客户端代码编写

参考官方文档吧,ui照着拖动设计,命名也不复杂就看官方的.ui文件修改名字。

https://doc.qt.io/qt-6.9/qtmqtt-subscriptions-example.html

本来想画一个类图直观描述一下其中mqtt类的一些属性方法的,发现官方文档写的太特么详细了,就拿这个qtmqttclient类来说,官方文档链接:https://doc.qt.io/qt-6.9/qmqttclient.html

效果

img

同样在mqttx的客户端也可以订阅这个主题发消息,也能实现收发,都看得到。