1.搭建MQTT环境
1.下载源码
1.在GitHub下载对应qt版本的源码
git clone git://code.qt.io/qt/qtmqtt.git -b 6.5.3
这里以6.5.3版本的为例。
这里使用的是VScode的终端,使用cmd也可以。
2.CMake 编译 Qt MQTT 模块
1.使用QT软件打开CMakeLists.txt。
编译成功文件夹里会生成一个build的文件夹,里面包含Desktop_Qt_6_5_3_MinGW_64_bit-Release这个文件。
3.添加QT MQTT模块
这里将编译好的文件放到Qt的安装目录中。
1.移动bin文件里的Qt6Mqtt.dll。注意两者的路径
2.移动include里的QtMqtt文件夹。注意两者的路径
3.移动lib文件夹
注意路径。
Qt6Mqtt文件夹
Qt6Mqtt.pc文件
libQt6Mqtt.a Qt6Mqtt.prl文件。
4.移动mkspecs文件
5.modules文件夹
6.复制替换头文件的内容
7.至此mqtt环境已经全部配置完成了。下面我们可以进行验证一下
4.验证测试
进入到例示程序里面选中该文件。
点击运行,如果之前配置没有出错的话,这里可以出现运行界面。
连接EMQ 免费提供的公共 MQTT Broker,基于 EMQX Platform 构建。服务器访问详情如下:
代理:broker.emqx.io
TCP 端口:1883
SSL/TLS 端口:8883
WebSocket 端口:8083
SSL/TLS 端口:8883
安全 WebSocket 端口:8084
2.MQTT的使用
1.添加相关头文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore/QDateTime>
#include <QtMqtt/QMqttClient>
#include <QtWidgets/QMessageBox>
2.窗口
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//MQTT客户端设置
m_client = new QMqttClient(this);
//从界面上获取MQTT服务器的主机名和端口号
m_client->setHostname(ui->lineEditHost->text());
m_client->setPort(static_cast<quint16>(ui->spinBoxPort->value()));
//信号槽连接
//状态变化处理 调用updateLogStateChange更新当前的状态
connect(m_client, &QMqttClient::stateChanged, this, &MainWindow::updateLogStateChange);
//断开连接处理 当断开时调用brokerDisconnected
connect(m_client, &QMqttClient::disconnected, this, &MainWindow::brokerDisconnected);
//消息接收处理 当接收到MQTT消息时,记录时间戳,主题和消息内容到日志
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);
});
//Ping相应处理
connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() {
const QString content = QDateTime::currentDateTime().toString()
+ QLatin1String(" PingResponse")
+ QLatin1Char('\n');
ui->editLog->insertPlainText(content);
});
//动态更新设置
// 主机名文本框内容变化时,自动更新客户端设置
connect(ui->lineEditHost, &QLineEdit::textChanged, m_client, &QMqttClient::setHostname);
//端口号变化时,通过setClientPort函数更新客户端设置
connect(ui->spinBoxPort, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::setClientPort);
//初始化日志状态
updateLogStateChange();
}
3.进行连接
void MainWindow::on_buttonConnect_clicked()
{
if (m_client->state() == QMqttClient::Disconnected) {
ui->lineEditHost->setEnabled(false);
ui->spinBoxPort->setEnabled(false);
ui->buttonConnect->setText(tr("Disconnect")); //改变界面显示
m_client->connectToHost(); //发起连接请求
} else {
ui->lineEditHost->setEnabled(true);
ui->spinBoxPort->setEnabled(true);
ui->buttonConnect->setText(tr("Connect"));
m_client->disconnectFromHost(); //断开连接
}
}
4.初始化日志状态
void MainWindow::updateLogStateChange()
{
const QString content = QDateTime::currentDateTime().toString()
+ QLatin1String(": State Change")
+ QString::number(m_client->state())
+ QLatin1Char('\n');
ui->editLog->insertPlainText(content);
}
5.断开连接
void MainWindow::brokerDisconnected()
{
ui->lineEditHost->setEnabled(true);
ui->spinBoxPort->setEnabled(true);
ui->buttonConnect->setText(tr("Connect"));
}
6.端口设置函数
void MainWindow::setClientPort(int p)
{
m_client->setPort(static_cast<quint16>(p));
}
7.消息发布函数
从界面获取主题和消息内容
调用 MQTT 客户端发布消息
错误处理:发布失败时显示错误对话框
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"));
}
8.主题订阅函数
从界面获取订阅主题
调用 MQTT 客户端订阅主题
错误处理:订阅失败时显示错误对话框
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;
}
}