当前位置: 首页 > news >正文

qtmqtt: 一个开源且好用的mqtt开源客户端

目录

1.背景

2.安装

2.1.通过 Qt Maintenance Tool 安装(推荐)

2.2.源码编译(适用于维护工具无对应版本)

3.核心类与关键接口

4.基本使用

5.实用开发技巧

6.常见问题与解决方案

7.总结


1.背景

        MQTT是机器对机器(M2M)/物联网(IoT)连接协议。它被设计为一个极其轻量级的发布/订阅消息传输协议。对于需要较小代码占用空间和/或网络带宽非常宝贵的远程连接非常有用,是专为受限设备和低带宽、高延迟或不可靠的网络而设计。这些原则也使该协议成为新兴的“机器到机器”(M2M)或物联网(IoT)世界的连接设备,以及带宽和电池功率非常高的移动应用的理想选择。例如,它已被用于通过卫星链路与代理通信的传感器、与医疗服务提供者的拨号连接,以及一系列家庭自动化和小型设备场景。它也是移动应用的理想选择,因为它体积小,功耗低,数据包最小,并且可以有效地将信息分配给一个或多个接收器。   

        MQTT的框架结构如下:

qtmqtt是qt官方提供的用于实现 MQTT 协议客户端功能的扩展模块,基于 MQTT 3.1.1 协议,支持 Qt5(5.10+)和 Qt6 版本,可用于物联网(IoT)、消息推送、设备通信等场景。

https://doc.qt.io/qt-6/zh/qtmqtt-overview.html

2.安装

Qt MQTT 是 Qt 的扩展模块,需单独安装(默认不包含在基础安装中),支持 Qt5.10 + 和 Qt6。

2.1.通过 Qt Maintenance Tool 安装(推荐)

  1. 打开 Qt 维护工具(Qt Maintenance Tool,通常在 Qt 安装目录的MaintenanceTool.exe);
  2. 选择 “添加或移除组件”,输入 Qt 账号密码;
  3. 在组件列表中,展开你的 Qt 版本(如 Qt 6.5.0),找到 “Additional Libraries”→“Qt MQTT”,勾选对应平台的模块(如 Windows 下的 MSVC 或 MinGW 版本);
  4. 点击 “安装”,等待完成。

2.2.源码编译(适用于维护工具无对应版本)

1.获取源码

从 Qt 官方仓库克隆源码:

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

切换到与你的 Qt 版本匹配的分支(如 Qt6.5 对应分支6.5):

cd qtmqtt && git checkout 6.5

2.编译源码

  • 用 Qt Creator 打开源码目录中的qtmqtt.pro
  • 在项目配置中选择目标编译器(与你的 Qt 版本一致);
  • 构建项目(Build),生成库文件(.lib/.a.dll/.so)。

3.安装到 Qt 目录

1) 编译完成后,通过make install(Linux/macOS)或nmake install(Windows)将库安装到 Qt 的默认库目录(确保 Qt 能识别)。

2) 直接用编译出的库文件。

3.核心类与关键接口

Qt MQTT 的核心功能围绕几个关键类展开,理解这些类的作用是使用的基础:

1. QMqttClient(客户端核心类)

负责与 MQTT 服务器建立连接、管理连接状态、发布消息等,是整个模块的核心。

关键方法

  • setHostname(const QString &host):设置服务器地址(域名或 IP);
  • setPort(quint16 port):设置端口(默认 1883,SSL 通常用 8883);
  • setClientId(const QString &id):设置客户端唯一 ID(服务器通过 ID 识别客户端,建议唯一);
  • setUsername(const QString &user) / setPassword(const QString &pwd):设置认证信息(若服务器需要);
  • connectToHost() / disconnectFromHost():连接 / 断开服务器;
  • publish(const QMqttTopicName &topic, const QByteArray &message, int qos = 0, bool retain = false):发布消息(返回是否成功);
  • subscribe(const QString &topic, int qos = 0):订阅主题(返回 QMqttSubscription 指针,用于管理订阅)。

关键信号

  • stateChanged(QMqttClient::ClientState state):连接状态变化(断开 / 连接中 / 已连接);
  • errorOccurred(QMqttClient::ClientError error):发生错误时触发(如连接失败、认证失败);
  • connected():成功连接服务器后触发;
  • disconnected():断开连接后触发。

2. QMqttSubscription(订阅管理类)

由 QMqttClient::subscribe() 返回,用于管理订阅的主题,接收该主题的消息。

关键信号

  • messageReceived(const QByteArray &message, const QMqttTopicName &topic):收到订阅主题的消息时触发(核心信号,需绑定到自定义槽函数处理消息);
  • stateChanged(QMqttSubscription::SubscriptionState state):订阅状态变化(如订阅中 / 已订阅 / 订阅失败)。

3.QMqttTopicName(主题名类)

封装 MQTT 主题名,提供主题合法性检查(如避免非法字符),发布 / 订阅时需用此类或直接传入字符串(内部会自动转换)。

4.基本使用

使用前需在项目中配置 MQTT 模块,核心类为QMqttClient(客户端)、QMqttSubscription(订阅)。

1.项目配置(.pro 文件)

在 Qt 项目的.pro文件中添加 MQTT 模块:

QT += mqtt

2.核心功能示例

以下是一个完整的 MQTT 客户端示例,实现 “连接服务器→订阅主题→发布消息→接收消息” 的流程。

示例代码(C++)

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QMqttClient>  // MQTT客户端类
#include <QMqttSubscription>  // 订阅类QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:// 连接/断开服务器void on_connectBtn_clicked();// 发布消息void on_publishBtn_clicked();// 处理连接状态变化void onStateChanged(QMqttClient::ClientState state);// 处理错误void onErrorOccurred(QMqttClient::ClientError error);// 处理接收到的消息void onMessageReceived(const QByteArray &message, const QMqttTopicName &topic);private:Ui::MainWindow *ui;QMqttClient *mqttClient;  // MQTT客户端实例
};
#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);// 初始化MQTT客户端mqttClient = new QMqttClient(this);// 设置默认服务器(可替换为公共测试服务器:test.mosquitto.org)ui->hostEdit->setText("test.mosquitto.org");ui->portSpin->setValue(1883);  // MQTT默认端口ui->topicEdit->setText("qt/mqtt/test");  // 测试主题// 绑定信号槽(状态变化、错误、消息接收)connect(mqttClient, &QMqttClient::stateChanged, this, &MainWindow::onStateChanged);connect(mqttClient, &QMqttClient::errorOccurred, this, &MainWindow::onErrorOccurred);
}MainWindow::~MainWindow() {delete ui;
}// 连接/断开服务器
void MainWindow::on_connectBtn_clicked() {if (mqttClient->state() == QMqttClient::Connected) {// 已连接:断开连接mqttClient->disconnectFromHost();ui->connectBtn->setText("连接");} else {// 未连接:设置服务器参数并连接mqttClient->setHostname(ui->hostEdit->text());  // 服务器地址mqttClient->setPort(ui->portSpin->value());     // 端口// 可选:设置客户端ID(建议唯一,默认自动生成)mqttClient->setClientId("QtMqttClient_" + QString::number(qrand()));// 可选:设置用户名/密码(若服务器需要)// mqttClient->setUsername("user");// mqttClient->setPassword("pass");// 连接服务器mqttClient->connectToHost();}
}// 发布消息
void MainWindow::on_publishBtn_clicked() {if (mqttClient->state() != QMqttClient::Connected) {QMessageBox::warning(this, "错误", "未连接到服务器!");return;}// 发布消息:主题、内容、QoS(0/1/2)、是否保留QMqttTopicName topic(ui->topicEdit->text());QByteArray message = ui->messageEdit->text().toUtf8();mqttClient->publish(topic, message, 1, false);  // QoS=1(确保消息至少到达一次)ui->logEdit->append("发布消息:" + message);
}// 处理连接状态变化
void MainWindow::onStateChanged(QMqttClient::ClientState state) {switch (state) {case QMqttClient::Disconnected:ui->logEdit->append("已断开连接");break;case QMqttClient::Connecting:ui->logEdit->append("正在连接...");break;case QMqttClient::Connected:ui->logEdit->append("已连接到服务器");ui->connectBtn->setText("断开");// 连接成功后订阅主题auto subscription = mqttClient->subscribe(ui->topicEdit->text(), 1);  // QoS=1if (subscription) {connect(subscription, &QMqttSubscription::messageReceived,this, &MainWindow::onMessageReceived);ui->logEdit->append("已订阅主题:" + ui->topicEdit->text());}break;}
}// 处理错误
void MainWindow::onErrorOccurred(QMqttClient::ClientError error) {ui->logEdit->append("错误:" + mqttClient->errorString());
}// 处理接收到的消息
void MainWindow::onMessageReceived(const QByteArray &message, const QMqttTopicName &topic) {ui->logEdit->append(QString("收到消息(主题:%1):%2").arg(topic.name()).arg(QString(message)));
}

5.实用开发技巧

在实际开发中,除了基础功能,还需处理断线重连、消息可靠性、加密等问题,以下是常用技巧:

1.断线自动重连

MQTT 客户端可能因网络波动断开连接,需实现自动重连机制:

// 在断开连接时启动重连定时器
connect(mqttClient, &QMqttClient::disconnected, this, [=]() {ui->logEdit->append("连接断开,将在5秒后重试...");QTimer::singleShot(5000, this, [=]() {if (mqttClient->state() == QMqttClient::Disconnected) {mqttClient->connectToHost(); // 重试连接}});
});

2.遗嘱消息(Last Will and Testament)

当客户端异常断开(如崩溃、网络中断),服务器会自动向指定主题发布 “遗嘱消息”,用于通知其他客户端:

// 配置遗嘱消息(必须在连接前设置)
mqttClient->setWillTopic("qt/mqtt/will"); // 遗嘱主题
mqttClient->setWillMessage("客户端意外离线"); // 遗嘱内容
mqttClient->setWillQoS(1); // 遗嘱消息的QoS等级
mqttClient->setWillRetain(false); // 是否保留遗嘱消息

3.SSL 加密连接(支持 TLS)

对于需要加密的场景(如生产环境),需配置 SSL 证书:

// 初始化SSL配置
QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
// 加载CA证书(若服务器使用自签名证书,需指定CA)
QList<QSslCertificate> caCerts = QSslCertificate::fromPath("ca.crt"); // 替换为实际证书路径
if (!caCerts.isEmpty()) {sslConfig.setCaCertificates(caCerts);
}
// 禁用证书验证(仅测试用,生产环境不建议)
// sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);// 应用SSL配置并连接
mqttClient->setSslConfiguration(sslConfig);
mqttClient->setPort(8883); // SSL默认端口
mqttClient->connectToHost();

4.主题通配符使用

订阅时支持通配符匹配多个主题,简化订阅逻辑:

  • +:匹配单个层级(如 sensors/+/temp 匹配 sensors/room1/tempsensors/room2/temp);
  • #:匹配所有子层级(如 sensors/# 匹配 sensors/room1/tempsensors/room2/humidity,必须放在末尾)。

示例:

// 订阅所有传感器相关主题
mqttClient->subscribe("sensors/#", 1);

6.常见问题与解决方案

1.连接失败:“Connection refused: Not authorized”

  • 原因:服务器需要认证,但未设置用户名 / 密码,或认证信息错误。
  • 解决:用 setUsername() 和 setPassword() 配置正确的认证信息。

2.发布消息后未收到

  • 检查主题是否完全匹配(MQTT 主题区分大小写,如 test 和 Test 是不同主题);
  • 确认客户端已成功订阅主题(通过 QMqttSubscription::stateChanged 检查订阅状态);
  • 检查 QoS 等级:若服务器或中间节点不支持高 QoS(如 QoS 2),可能导致消息丢失。

3.Qt5 与 Qt6 兼容性差异

  • Qt6 中 QMqttClient::ClientError 枚举值名称略有调整(如 InvalidProtocolVersion 改为 ProtocolVersionError);
  • Qt6 移除了部分过时接口(如 QMqttClient::willTopic() 改为 willTopic() 的常量版本),迁移时需注意接口变化。

7.总结

Qt MQTT 适用于需要低带宽、高可靠性的消息通信场景,例如:

  • 物联网设备间通信(如传感器数据上报、设备控制指令);
  • 跨平台消息推送(桌面 / 移动设备接收服务器通知);
  • 分布式系统中的轻量级消息传递。

Qt MQTT 的优势在 基于 Qt 框架的开发场景 中尤为突出,尤其是:

  • 跨平台 GUI 应用(如物联网监控平台、设备管理工具);
  • 嵌入式设备(如传感器节点、工业控制器);
  • 需要与 Qt 其他模块(如网络、界面、硬件交互)深度协同的项目。

如果应用不基于 Qt 框架(如纯 Python 脚本、Java 后端),第三方客户端(如 paho-mqtt、Eclipse Paho Java)可能更合适;但如果是 Qt 开发,Qt MQTT 是性价比最高的选择。

参考:

http://mqtt.p2hp.com/

http://www.dtcms.com/a/531999.html

相关文章:

  • 数据仓库——总线架构详解
  • 软件中锁机制全解析:从线程到分布式锁
  • 郴州网站设计做外墙资料的网站
  • 【Swift】LeetCode 238.除自身以外数组的乘积
  • GitLab
  • GitHub等平台形成的开源文化正在重塑继任者
  • 【区块链学习笔记】17:以太坊中的GHOST协议
  • 【SpringAI】10.结构化输出
  • 递归经典例题
  • SpringMVC入门:配置、映射与参数处理​
  • 前端笔试复盘 | 知识点总结
  • 春招准备之Java基础篇
  • 有哪几个网站可以做贸易网站备案要多少天
  • 【编程语言】Java基础语法回顾,大学期末考试速通版(选择填空、程序、实践)
  • Redis(85)Redis缓存与Memcached缓存有何区别?
  • 【iOS】自动引用计数(一)
  • 有什么免费的网站wordpress 采集器
  • 网站建设创新成果网站营销如何做
  • 设计模式-享元模式(Flyweight)
  • TMS320C6000 VLIW架构并行编程实战:加速AI边缘计算推理性能
  • 算法学习记录08——并归的应用(LeetCode[315])
  • 【机器人学中的状态估计】3.6.6 习题证明
  • Kafka生产者详解(下):数据去重(幂等性)与数据有序
  • Data Ingestion: Architectural Patterns
  • 网站建设心得体会范文郑州男科医院排行哪家最好
  • 【datawhale秋训营】动手开发RAG系统(应急安全方向) TASK02
  • 怎么搜索整个网站内容网站怎么做成app
  • Python3 集合
  • 九冶建设有限公司官方网站sem优化怎么做
  • MATLAB基于灰靶决策模型的高校信息化设备供应商选择研究