前言
基于QT5.15版本,使用QtMqtt链接。
提示:以下是本篇文章正文内容,下面案例可供参考
QtMqtt编译
从QtMqtt[源码地址](https://github.com/qt/qtmqtt)克隆项目到本地。在Qt编译环境的include文件夹(根据配置的compiler会有不同的路径,windows默认路径是C:\Qt\Qt-5.15.2\include)内建立QtMqtt文件夹,将/src/mqtt目录下的头文件复制刚刚新建的QtMqtt文件夹内。编译目标环境的Release版本,生成链接库(windows是.dll文件和.lib文件)。将生成的链接库复制到编译环境的lib文件夹,windows环境还需要将.dll文件复制bin文件夹。注意:本人的目标机环境是Linux,以下代码均基于此实现
代码实现
1.引入库
在qpro文件内添加一行
LIBS += -lQt5Mqtt
2.头文件
代码如下(示例):
#ifndef MQTTCONSUMER_H
#define MQTTCONSUMER_H
#include <QtMqtt/qmqttclient.h>
#include <QTimer>
#include <QObject>
class Mqtt : public QObject
{
Q_OBJECT
public:
explicit Mqtt(QObject *parent = nullptr);
//设置最大延迟链接时间
void setReconnectMaxDelayTime(int i){m_maxDelay = i;}
//发送消息
void publishMessage(const QString &message, const QString &topic);
//增加订阅
void addTopic(const QString &topic);
//移除订阅
void removeTopic(const QString &topic);
public slots:
void subscribe();
private:
QMqttClient* _client = new QMqttClient() ;
QTimer *_timer = new QTimer(this);
//最大延迟连接时间
int m_maxDelay = 900000;
int m_time = 1000;
QStringList m_topics;
};
#endif // MQTTCONSUMER_H
3.cpp文件
#include "mqtt.h"
Mqtt::Mqtt(QObject *parent) : QObject(parent)
{
_client->setHostname("127.0.0.1");
_client->setPort(1883);
_client->connectToHost();
//链接断开时进行重连
connect(_client, &QMqttClient::disconnected, this, [this](){_timer->start(m_time);});
//链接成功时进行订阅
connect(_client, &QMqttClient::connected, this, [this](){subscribe();});
//有消息时进行消费
connect(_client, &QMqttClient::messageReceived, this, [](const QByteArray &message, const QMqttTopicName &topic) {
const QString content = QDateTime::currentDateTime().toString()
+ QLatin1String(" Received Topic: ")
+ topic.name()
+ QLatin1String(" Message: ")
+ message
+ QLatin1Char('\n');
qDebug() << content;
});
//触发重新计时器
connect(_timer, &QTimer::timeout, this, [this](){
//重新链接
_client->connectToHost();
//如果延迟时间小于最大延迟时间则加15秒
if(m_time < m_maxDelay){
m_time = m_time + 15000;
}
qDebug() << QString("reconnect times: %1").arg((m_time - 1000) / 15000);
//一定要停止当前的计时器
_timer->stop();
});
}
void Mqtt::publishMessage(const QString &message, const QString &topic)
{
if(_client->state() == QMqttClient::Connected){
qint32 localPublish = _client->publish(topic, message.toUtf8());
if(localPublish < 0){
qDebug() << QString("send message : %1 to topic: %2 faild.").arg(message).arg(topic);
}
}
}
void Mqtt::addTopic(const QString &topic)
{
if(!m_topics.contains(topic)){
m_topics << topic;
QMqttSubscription *localSubscribe = _client->subscribe(topic);
if(!localSubscribe){
qDebug() << QString("subscribe topic : %1 faild.").arg(topic);
}
else{
qDebug() << QString("subscribe topic : %1 succes.").arg(topic);
}
}
}
void Mqtt::removeTopic(const QString &topic)
{
_client->unsubscribe(topic);
m_topics.removeOne(topic);
}
void Mqtt::subscribe()
{
//链接成功后停止计时器,重置重连延迟时间,订阅主题
_timer->stop();
m_time = 1000;
for(QString topic : m_topics){
QMqttSubscription *localSubscribe = _client->subscribe(topic);
if(!localSubscribe){
qDebug() << QString("subscribe topic : %1 faild.").arg(topic);
}
else{
qDebug() << QString("subscribe topic : %1 succes.").arg(topic);
}
}
}
总结
由于目标机和开发机不是同一环境,涉及到交叉编译的情况,编译环境一定要搞清楚!!!