前言

基于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);
        }
    }
}



总结

由于目标机和开发机不是同一环境,涉及到交叉编译的情况,编译环境一定要搞清楚!!!

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐