MQTT客户端实用实例

一、MQTT简介

MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

二、前言

本文开发的代码开发基于Qt,版本4.8.4,运行环境:ubuntu 22.04。
采用了qmqtt的开源库。
本文项目下载路径:https://download.csdn.net/download/liuge3452/88422059

三、编译MQTT基础库

	 1. 下载MQTT开源库,qmqtt-qt4。
	 2. 解压后进入解压目录,可以看到如下文件和目录:


4. 命令终端执行qmake qmqtt.pro
5. 命令终端执行make
6. 也可以使用qtcreator 打开qmqtt.pro,然后手动编译。以上两种方法编译后,都会生成 .so的共享库。

四、编写MQTT客户端代码

4.1 PRO文件


TEMPLATE = app
TARGET = MQTTClientTester
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
QT       += network

QMAKE_ORIG_TARGET = $(TARGET)

unix {
    CONFIG(debug, debug|release) {
        LIBS += -lqmqtt
    } else {
        LIBS += -lqmqtt
    }
}
win32 {

    CONFIG(release, debug|release) {
        QMAKE_POST_LINK = $$QMAKE_COPY release\\*.exe $(CPS_ENV)\\bin
        LIBS += qmqtt.lib
    }
}
#install
{
      target.path = $$(CPS_ENV)/bin
      INSTALLS += target
}

SOURCES +=\
	mainwindow.cpp\
    main.cpp

HEADERS  += \
        mainwindow.h

4.2 头文件声明

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QObject>
#include <QMainWindow>
#include <QTabWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include <QTimer>
#include "qmqtt/qmqtt.h"
#include "qmqtt/qmqtt_global.h"
#include "qmqtt/qmqtt_client.h"
#include "qmqtt/qmqtt_message.h"


class  MainWindow : public QMainWindow
{
    Q_OBJECT

public:

    MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void on_publish();
    void on_start_connect();
    void on_connected();
    void on_disconnected();
    void on_subscribe();
    void on_connect_timeout();
    void mqtt_callback(const QMQTT::Message &msg);
private:

    QMQTT::Client     *m_mqtt_handle;

    QTimer      *m_connect_timer;

    QLineEdit   *m_ip_edit;
    QLineEdit   *m_port_edit;
    QLineEdit   *m_user_edit;
    QLineEdit   *m_psw_edit;
    QPushButton *m_connect_btn;

    QPushButton *m_subscribe_btn;
    QLineEdit   *m_subscribe_topic_edit;
    QTextEdit   *m_subscribe_list_edit;
    QTextEdit   *m_recv_msg_edit;

    QPushButton *m_send_btn;
    QLineEdit   *m_send_topic_edit;
    QTextEdit   *m_send_msg_edit;

    void MQTT_Publish(QString topic, QString msg);
};

#endif // MAINWINDOW_H

4.3 实现定义

#include "mainwindow.h"
#include <QHBoxLayout>
#include <QMessageBox>
#include <QGroupBox>
#include <QSettings>

extern QString g_cfg_path;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),m_mqtt_handle(NULL)
{
    QSettings set(g_cfg_path,QSettings::IniFormat,NULL);
    QString ip = set.value(QString("ip")).toString();
    int port = set.value(QString("port")).toInt();
    QString username = set.value(QString("username")).toString();
    QString userpsw = set.value(QString("userpsw")).toString();


    m_ip_edit = new QLineEdit(this);
    m_ip_edit->setPlaceholderText(tr("IP address"));
    m_ip_edit->setText(ip);

    m_port_edit = new QLineEdit(this);
    m_port_edit->setPlaceholderText(tr("Port"));
    m_port_edit->setText(QString::number( port));

    m_user_edit = new QLineEdit(this);
    m_user_edit->setPlaceholderText(tr("User name"));
    m_user_edit->setText(username);

    m_psw_edit = new QLineEdit(this);
    m_psw_edit->setPlaceholderText(tr("Password"));
    m_psw_edit->setText(userpsw);

    m_connect_btn = new QPushButton(tr("Connect"),this);
    connect(m_connect_btn,SIGNAL(clicked()),this,SLOT(on_start_connect()));

    m_send_btn = new QPushButton(tr("Publish"),this);
    connect(m_send_btn,SIGNAL(clicked()),this,SLOT(on_publish()));
    m_send_topic_edit = new QLineEdit(this);
    m_send_topic_edit->setText("remctl/request/nz_program_update/probackup");
    m_send_msg_edit = new QTextEdit(this);
    m_send_msg_edit->append(QString::fromLocal8Bit("{\"token\":\"123\",\"timestamp\":\"2019-03-01 09:30:08.000\",\"substation\":\"yyyyyyyyyyyy\",\"dev\":\"P_L2201A_19087ebc0c823f68a80d9cb616fcb8ed\"}"));

    m_subscribe_btn = new QPushButton(tr("Subscribe"),this);
    connect(m_subscribe_btn,SIGNAL(clicked()),this,SLOT(on_subscribe()));
    m_subscribe_topic_edit = new QLineEdit(this);
    m_subscribe_topic_edit->setText("nz_program_update/reponse/remctl/probackup");
    m_subscribe_list_edit = new QTextEdit(this);
    m_recv_msg_edit = new QTextEdit(this);

    m_connect_timer = new QTimer(this);
    m_connect_timer->setSingleShot(true);
    m_connect_timer->setInterval(10*1000);
    connect(m_connect_timer,SIGNAL(timeout()),this,SLOT(on_connect_timeout()));

    QHBoxLayout *layout1 = new QHBoxLayout;
    layout1->addWidget(m_ip_edit);
    layout1->addWidget(m_port_edit);
    layout1->addWidget(m_user_edit);
    layout1->addWidget(m_psw_edit);
    layout1->addWidget(m_connect_btn);


    QHBoxLayout *layout2 = new QHBoxLayout;
    layout2->addWidget(m_send_topic_edit);
    layout2->addWidget(m_send_btn);

    QHBoxLayout *layout3 = new QHBoxLayout;
    layout3->addWidget(m_subscribe_topic_edit);
    layout3->addWidget(m_subscribe_btn);

    QVBoxLayout *layout4 = new QVBoxLayout;
    layout4->addLayout(layout3);
    layout4->addWidget(m_subscribe_list_edit);
    layout4->addWidget(m_recv_msg_edit);

    QVBoxLayout *layout5 = new QVBoxLayout;
    layout5->addLayout(layout2);
    layout5->addWidget(m_send_msg_edit);

    QHBoxLayout *layout6 = new QHBoxLayout;
    layout6->addLayout(layout4);
    layout6->addLayout(layout5);

    QGroupBox *group_box = new QGroupBox(tr("Work plant--------------------------------------------------------------------------------------------------------------"),this);
    group_box->setLayout(layout6);

    QVBoxLayout *layout7 = new QVBoxLayout;
    layout7->addLayout(layout1);
    layout7->addWidget(group_box);

    QWidget *w = new QWidget(this);
    w->setLayout(layout7);
    setCentralWidget(w);

    setWindowTitle(tr("MQTT client tester"));

}

MainWindow::~MainWindow()
{


}

void MainWindow::on_publish()
{
    MQTT_Publish(m_send_topic_edit->text(),m_send_msg_edit->toPlainText());
}

void MainWindow::on_connected()
{
    m_connect_btn->setEnabled(true);
    connect(m_mqtt_handle,SIGNAL(received(QMQTT::Message)),this,SLOT(mqtt_callback(QMQTT::Message)));
    QMessageBox::information(this,tr("Message"),tr("Connect success"));
    m_connect_timer->stop();
}

void MainWindow::on_disconnected()
{
    disconnect(m_mqtt_handle,SIGNAL(connected()),this,SLOT(on_connected()));
    disconnect(m_mqtt_handle,SIGNAL(disconnected()),this,SLOT(on_connected()));
    disconnect(m_mqtt_handle,SIGNAL(received(QMQTT::Message)),this,SLOT(mqtt_callback(QMQTT::Message)));
    delete m_mqtt_handle;
    m_mqtt_handle = NULL;
    QMessageBox::information(this,tr("Message"),tr("Disconnected"));

}

void MainWindow::on_start_connect()
{
    if(!m_mqtt_handle)
    {
        delete m_mqtt_handle;
        m_mqtt_handle = NULL;
    }

    m_connect_btn->setEnabled(false);
    m_mqtt_handle = new QMQTT::Client(QHostAddress(m_ip_edit->text()),m_port_edit->text().toInt());
    m_mqtt_handle->setUsername(m_user_edit->text());
    m_mqtt_handle->setPassword(m_psw_edit->text());
    m_mqtt_handle->setAutoReconnect(true);
    connect(m_mqtt_handle,SIGNAL(connected()),this,SLOT(on_connected()));
    connect(m_mqtt_handle,SIGNAL(disconnected()),this,SLOT(on_connected()));
    m_mqtt_handle->connectToHost();
    m_connect_timer->start();
}

void MainWindow::on_subscribe()
{
    qint16 res  = m_mqtt_handle->subscribe(m_subscribe_topic_edit->text(),0);
    if(res > 0)
    {
        m_subscribe_list_edit->append(m_subscribe_topic_edit->text());
    }
}

void MainWindow::on_connect_timeout()
{
    m_connect_btn->setEnabled(true);
    QMessageBox::information(this,tr("Message"),tr("Connect timeout"));
}

void MainWindow::mqtt_callback(const QMQTT::Message &msg)
{
    QString topic = msg.topic();
    std::string data = msg.payload().data();
    qDebug()<<"RECV:"<<topic<<QString::fromUtf8(data.data());
    m_recv_msg_edit->append(tr("TOPIC:") + topic);
    m_recv_msg_edit->append(tr("data:") + QString::fromUtf8(data.data()));
    m_recv_msg_edit->append("------------------------------------------");
}

void MainWindow::MQTT_Publish(QString topic,QString msg)
{
    qDebug()<<topic<<msg;


    static quint16 _number = 0;
    QMQTT::Message message(_number++, topic,msg.toUtf8());
    m_mqtt_handle->publish(message);
}

五、运行MQTT客户端代码

正常编译后,就可以执行了,如下图,实现了MQTT的主题订阅,按照主题发送消息,以及展示订阅的消息等,是很实用的MQTT测试客户端工具,在经过适当的改造后,可以应用与很多场合。

六、总结

本文通过介绍MQTT,介绍编译qmqtt的方法,以及基于此开源库实现MQTT客户端的方法,最终实现了基于主题的消息发送、订阅等功能,希望可以帮助到刚接触MQTT的朋友,感谢大家的阅读。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在安卓上创建MQTT客户端实例,可以按照以下步骤进行操作: 1. 导入MQTT库:在项目的build.gradle文件中添加以下依赖项:implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0' 2. 创建MqttConnectOptions对象,并设置相应参数,例如连接的用户名、密码、服务器地址等等。 3. 创建MqttAsyncClient对象,并传入服务器地址和客户端ID等参数。 4. 设置MqttAsyncClient对象的回调函数,以便在收到消息时进行处理。 5. 调用MqttAsyncClient对象的connect()方法,连接到MQTT服务器。 6. 使用MqttAsyncClient对象的subscribe()和publish()方法进行订阅和发布消息。 示例代码如下: ``` String broker = "tcp://mqtt.eclipse.org:1883"; String clientId = "AndroidClient"; String username = "your-username"; String password = "your-password"; MqttConnectOptions options = new MqttConnectOptions(); options.setUserName(username); options.setPassword(password.toCharArray()); MqttAsyncClient client = new MqttAsyncClient(broker, clientId); client.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable throwable) { // 连接断开处理 } @Override public void messageArrived(String s, MqttMessage mqttMessage) throws Exception { // 收到消息处理 } @Override public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { // 消息发送完毕处理 } }); client.connect(options); client.subscribe("topic/test", 0); String message = "Hello, MQTT!"; client.publish("topic/test", message.getBytes(), 0, false); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值