Ubuntu16.04LTS环境下搭建MQTT服务器以及QT实现MQTT客户端

MQTT服务器搭建

使用EMQX搭建MQTT服务器,EMQX 4.2.14 for Ubuntu 16.04下载
下载zip包,选择安装方式为zip,cpu架构选择x86_64

Ubuntu16.04LTS环境下搭建MQTT服务器以及QT实现MQTT客户端_第1张图片
按照网页的指示进行下载、安装即可。
下载后按照网页指示,输入对应的命令,就可以在ubuntu解压emqx,解压完成直接进入文件夹运行emqx。
在这里插入图片描述

emqx开始运行后,进入浏览器,输入ip地址+:18083或是127.0.0.1:18083,输入账户admin,密码public,就能够打开MQTT控制台。Ubuntu16.04LTS环境下搭建MQTT服务器以及QT实现MQTT客户端_第2张图片
停止emqx:
在这里插入图片描述

QT实现MQTT客户端

移植MQTT库

可选用的库有很多,移植方式有很多,可以将源码编译过后将库导入工程,也可以直接将源码拷贝如工程使用。直接将源码拷贝到工程目录下
这里参考的是这篇博文:Linux Qt下MQTT模块的导入(源码移植)
选择的库为qmqtt-master,库只支持MQTTV3.0和MQTTV3.1协议,暂时还不支持MQTTV5.0协议,直接拷贝源码到工程目录下。
好处就是可以直接查看函数源文件,且移植非常方便,只要将源码下载下来,将源码目录中/src/mqtt文件夹整个cp到工程目录下。将文件夹内的.cpp和.h文件添加进工程目录,就完成了。

在工程内添加库

接下来需要在工程里添加MQTT的.cpp和.h文件,查看一下要添加的文件
Ubuntu16.04LTS环境下搭建MQTT服务器以及QT实现MQTT客户端_第3张图片
在.pro里面添加:
在这里插入图片描述
Ubuntu16.04LTS环境下搭建MQTT服务器以及QT实现MQTT客户端_第4张图片
执行qmake,重新构建工程,有报错的地方就修改一下,不报错就算移植完成了

QT程序编写

程序与云平台的通信格式采用JSON,定义一个类
关于具体实现,qmqtt_master有给一个例子,可以参考:

class GatawayToCloud : public QObject{
    Q_OBJECT
public:
    explicit GatawayToCloud(QObject *parent = 0);
    ~GatawayToCloud();

private:
    QMQTT::Client * mqtt_client;
    QHostAddress host;
    quint16 port;
    QString clientID;
    QString userName;
    QByteArray password;
    QTimer * timer;
    bool autoReconncetFlag;
    QMQTT::Message msgFromCloud;
    QMQTT::Message msgToCloud;

signals:
    void revMqttMsg(QString,QJsonArray);
    void revMqttMsg(QString,QJsonObject);
    void revMqttMsg(QString,QString);
    void revMqttMsg(QString,QByteArray);

private slots:
    void timeOut(void);
    void receiveCloudMessage(QMQTT::Message message);

public:
    void connectToCloud(void);
    void disconnectFromCloud(void);
    void setHost(QString);
    void setPort(quint16);
    void setClientID(QString);
    void setUserName(QString);
    void setPassword(QByteArray);
    void connectState(void);
    bool isConnected(void);
    void subscribeTopic(const QString,qint8);
    void unsubscribeTopic(const QString);
    void publishMessage(const QString,QByteArray);
};

类实现:

GatawayToCloud::GatawayToCloud(QObject *parent) : QObject (parent)
{
    mqtt_client = new QMQTT::Client(QHostAddress("192.168.1.188"),1883);
    /*disconnect when init*/
    mqtt_client->disconnectFromHost();

    autoReconncetFlag =false;
    /*timer*/
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(timeOut()));
    timer->start(5000);
}

GatawayToCloud::~GatawayToCloud()
{
    timer->stop();
}

void GatawayToCloud::timeOut()
{
    if(!autoReconncetFlag)
        return;
    if(mqtt_client->connectionState() != QMQTT::ConnectionState::STATE_CONNECTED ){
        connectState();
        mqtt_client->disconnectFromHost();
        connectToCloud();
    }
}

void GatawayToCloud::receiveCloudMessage(QMQTT::Message message)
{
    qDebug()<<("receive cloud message");
    QString topic = message.topic();
    QByteArray load = message.payload();
    emit revMqttMsg(topic,load);

//    QJsonDocument json_file = QJsonDocument::fromJson(load);

//    //plain text
//    if(json_file.isEmpty()){
//        emit revMqttMsg(topic,(QString)load);
//    }
//    //json
//    if(!json_file.array().isEmpty())
//        emit revMqttMsg(topic,json_file.array());
//    else if(!json_file.object().isEmpty()){
//        emit revMqttMsg(topic,json_file.object());
//    }
}

void GatawayToCloud::connectToCloud()
{
    mqtt_client->setKeepAlive(150);
    mqtt_client->setHost(host);
    mqtt_client->setPort(port);
    mqtt_client->setClientId(clientID);
    mqtt_client->setUsername(userName);
    mqtt_client->setPassword(password);
    mqtt_client->cleanSession();
    mqtt_client->setVersion(QMQTT::MQTTVersion::V3_1_0);

    mqtt_client->connectToHost();
    /*start auto reconnect*/
    autoReconncetFlag = true;
    /**/
    //connect(mqtt_client,SIGNAL(received),this,SLOT(receiveCloudMessage));
    connect(mqtt_client, SIGNAL(received(QMQTT::Message)),this, SLOT(receiveCloudMessage(QMQTT::Message)));
}

void GatawayToCloud::disconnectFromCloud()
{
    /*stop auto reconnect*/
    autoReconncetFlag = false;

    mqtt_client->disconnectFromHost();
}

void GatawayToCloud::setHost(QString hostAddr)
{
    host.setAddress(hostAddr);
}

void GatawayToCloud::setPort(quint16 hostPort)
{
    port = hostPort;
}

void GatawayToCloud::setClientID(QString cltID)
{
    clientID = cltID;
}

void GatawayToCloud::setUserName(QString usrNm)
{
    userName = usrNm;
}

void GatawayToCloud::setPassword(QByteArray hostPassword)
{
    password = hostPassword;
}

void GatawayToCloud::connectState()
{
    if(mqtt_client->connectionState() == QMQTT::ConnectionState::STATE_INIT){
        qDebug()<<("mqtt state: connect init");
    }else if(mqtt_client->connectionState() == QMQTT::ConnectionState::STATE_CONNECTING){
        qDebug()<<("mqtt state: connect connecting");
    }else if(mqtt_client->connectionState() == QMQTT::ConnectionState::STATE_DISCONNECTED){
        qDebug()<<("mqtt state: connect disconncet");
    }else if(mqtt_client->connectionState() == QMQTT::ConnectionState::STATE_CONNECTED){
        qDebug()<<("mqtt state: connected");
    }
}

bool GatawayToCloud::isConnected()
{
    return mqtt_client->connectionState()==QMQTT::ConnectionState::STATE_CONNECTED;
}

void GatawayToCloud::subscribeTopic(const QString topic,qint8 qos=0)
{
    if(mqtt_client->connectionState() != QMQTT::ConnectionState::STATE_CONNECTED){
        qDebug()<<("unconnected to mqtt,subcribe fail");
        return;
    }
    qDebug()<<("subcribe topic"+topic);
    mqtt_client->subscribe(topic,qos);
}

void GatawayToCloud::unsubscribeTopic(const QString topic)
{
    if(mqtt_client->connectionState() != QMQTT::ConnectionState::STATE_CONNECTED){
        qDebug()<<("unconnected to mqtt,unsubcribe fail");
        return;
    }
    qDebug()<<("unsubcribe topic"+topic);
    mqtt_client->unsubscribe(topic);
}

void GatawayToCloud::publishMessage(const QString topic, QByteArray msg)
{
    if(mqtt_client->connectionState() != QMQTT::ConnectionState::STATE_CONNECTED){
       qDebug()<<("unconnected to mqtt,publish fail");
        return;
    }
    qDebug()<<("publish topic   "+topic);
    /*Message(const quint16 id, const QString &topic, const QByteArray &payload,
                     const quint8 qos = 0, const bool retain = false, const bool dup = false);*/
    QMQTT::Message message((quint16)0x1000,topic,msg);
    mqtt_client->publish(message);
}

界面设计
Ubuntu16.04LTS环境下搭建MQTT服务器以及QT实现MQTT客户端_第5张图片

功能实现部分槽函数
云端消息接收及显示

/*接收到云端消息*/
void MainWindow::receiveCloudMsg(QString topic, QJsonArray json_array)
{
    QString msg_str;
    msg_str += QString("Topic JsonArray:"+topic+"\r\n");
    QJsonDocument json_file;
    json_file.setArray(json_array);
    QByteArray msg_array;
    msg_array += json_file.toJson();
    msg_str += msg_array;
    ui->textEdit_receiveFromCloud->append(msg_str);
}

void MainWindow::receiveCloudMsg(QString topic, QJsonObject json_object)
{
    QString msg_str;
    msg_str += QString("Topic JsonObject:"+topic+"\r\n");
    QJsonDocument json_file;
    json_file.setObject(json_object);
    QByteArray msg_array;
    msg_array += json_file.toJson();
    msg_str += msg_array;
    ui->textEdit_receiveFromCloud->append(msg_str);
}

void MainWindow::receiveCloudMsg(QString topic, QString str)
{
    ui->textEdit_receiveFromCloud->append(QString("Topic String:"+topic+"\r\n") + str);
}

PushButton控件槽函数

void MainWindow::on_pushButton_connect_clicked()
{
    //从textedit控件内获取参数
    mqttClient->setHost(ui->textEdit_IPaddr->toPlainText());
    mqttClient->setPort(ui->textEdit_port->toPlainText().toUInt());
    mqttClient->setClientID(ui->textEdit_clientID->toPlainText());
    mqttClient->setUserName(ui->textEdit_userName->toPlainText());
    mqttClient->setPassword(ui->textEdit_passWord->toPlainText().toUtf8());
    //连接
    mqttClient->connectToCloud();
    connect(mqttClient,SIGNAL(revMqttMsg(QString,QJsonArray)),this,SLOT(receiveCloudMsg(QString, QJsonArray)));
    connect(mqttClient,SIGNAL(revMqttMsg(QString,QJsonObject)),this,SLOT(receiveCloudMsg(QString, QJsonObject)));
    connect(mqttClient,SIGNAL(revMqttMsg(QString,QString)),this,SLOT(receiveCloudMsg(QString, QString)));
    connect(mqttClient,SIGNAL(revMqttMsg(QString,QByteArray)),this,SLOT(receiveCloudMsg(QString, QByteArray)));
}

void MainWindow::on_pushButton_publish_clicked()
{
    QByteArray msg ;
    msg += ui->textEdit_sendToCloud->toPlainText();

    qDebug()<<msg;
//    QJsonObject tmp_object;
//    tmp_object.insert("msg","hello");
//    QJsonDocument tmp_doc;
//    tmp_doc.setObject(tmp_object);
//    msg = tmp_doc.toJson();
    mqttClient->publishMessage(ui->textEdit_topic->toPlainText(),msg);
}

void MainWindow::on_pushButton_subscribe_clicked()
{
    /*订阅主题,安全等级QoS0*/
    mqttClient->subscribeTopic(ui->textEdit_topic->toPlainText(),0);
}



void MainWindow::on_pushButton_unsubscribe_clicked()
{
    /*取消订阅主题*/
    mqttClient->unsubscribeTopic(ui->textEdit_topic->toPlainText());
}

void MainWindow::on_pushButton_clear_clicked()
{
    ui->textEdit_receiveFromCloud->clear();
}

你可能感兴趣的:(嵌入式\linux\QT,qt,服务器,ubuntu)