mqtt协议目前是物联网领域使用最广的协议了,比如阿里云物联网平台与设备就是采用的mqtt协议。mqtt协议的介绍,网上已经非常多,下面是几个关键点:
MQTT协议
- 基于TCP协议,设备是客户端,云服务器是服务端;
- 基于发布/订阅消息机制来实现数据交互,客户端可以发布和订阅多个topic(主题),客户端1发布某个topic,客户端2订阅某个topic,这样客户端2就能接收到客户端1发出的数据了;
- topic(主题)可以理解为设备要对外发布数据或者接收的指令。比如,上传某个或者某些数据定义为一个topic;
- 综上基本就清楚数据是如何交互的了。
编译MQTT客户端
- 下载一个Git客户端;
- 下载qmqtt源码qmqtt ,打开要克隆的目录
- 用QtCreator打开Pro文件,如果是Windows上编译,记得添加 “CONFIG += NO_UNIT_TESTS”
- 直接编译会提示找不到"perl",这里可以直接下载安装一个,如果你安装了Git,里面会自带一个,我们只需要把perl的目录,添加到环境变量PATH中;
- 然后就能编译通过了;
将MQTT添加到系统模块
在编译好的目录中,将对应的文件放到Qt的安装目录,就能直接在Pro文件中添加 QT += qmqtt,然后添加头文件就可以使用了,比每次添加动态库方便和优雅一些.
对应存放位置:
编译文件(D:\Git\qmqtt\build-qmqtt-unknown-Debug) | Qt安装目录(D:\Qt\Qt5.7.0\5.7\msvc2013_64) |
---|---|
\include\QtQmqtt | \include |
\bin\Qt5Qmqtt.dll Qt5Qmqttd.dll | \bin |
\lib\Qt5Qmqttd.lib Qt5Qmqtt.lib Qt5Qmqtt.prl Qt5Qmqttd.prl | \lib |
\mkspecs\modules\qt_lib_qmqtt.pri | \mkspecs\modules |
使用qmqtt库
在pro文件中添加
QT += network
QT += qmqtt
主要代码如下,也可以参考Github上的说明,使用还是非常简单方便。
void MainWindow::ConnectHost()
{
client = new QMQTT::Client(QHostAddress("44.232.120.109"), 1883);
client->setClientId("00003138");
client->setUsername("admin");
client->setPassword("admin");
connect(client, SIGNAL(connected()), this, SLOT(OnConnected()));
connect(client, SIGNAL(error(const QMQTT::ClientError)), this, SLOT(OnError(const QMQTT::ClientError)));
connect(client, SIGNAL(subscribed(const QString& , const quint8)), this, SLOT(OnSubscribeData(const QString& , const quint8)));
connect(client, SIGNAL(received(const QMQTT::Message&)), this, SLOT(OnReceived(const QMQTT::Message&)));
client->connectToHost();
}
//订阅成功槽
void MainWindow::OnSubscribeData(const QString &topic, const quint8 qos)
{
qDebug() << topic << qos;
}
//连接服务器成功
void MainWindow::OnConnected()
{
qDebug() << "sub" ;
client->subscribe("hello/1234", 0);
}
//连接错误信息
void MainWindow::OnError(const QMQTT::ClientError error)
{
qDebug() << "error:" << error << client->host().toString() << client->hostName();
}
//数据接收
void MainWindow::OnReceived(const QMQTT::Message &message)
{
qDebug() << "recv"
<< message.topic()
<< QString::fromLocal8Bit(message.payload())
<< message.qos()
<< message.id();
//发布数据
static int id = 1;
QMQTT::Message msg;
msg.setId(id++);
msg.setQos(1);
msg.setTopic("hello/123");
QByteArray ar;
msg.setPayload(ar.setNum(id));
client->publish(msg);
}