使用EMQX搭建MQTT服务器,EMQX 4.2.14 for Ubuntu 16.04下载
下载zip包,选择安装方式为zip,cpu架构选择x86_64
按照网页的指示进行下载、安装即可。
下载后按照网页指示,输入对应的命令,就可以在ubuntu解压emqx,解压完成直接进入文件夹运行emqx。
emqx开始运行后,进入浏览器,输入ip地址+:18083或是127.0.0.1:18083,输入账户admin,密码public,就能够打开MQTT控制台。
停止emqx:
可选用的库有很多,移植方式有很多,可以将源码编译过后将库导入工程,也可以直接将源码拷贝如工程使用。直接将源码拷贝到工程目录下
这里参考的是这篇博文:Linux Qt下MQTT模块的导入(源码移植)
选择的库为qmqtt-master,库只支持MQTTV3.0和MQTTV3.1协议,暂时还不支持MQTTV5.0协议,直接拷贝源码到工程目录下。
好处就是可以直接查看函数源文件,且移植非常方便,只要将源码下载下来,将源码目录中/src/mqtt文件夹整个cp到工程目录下。将文件夹内的.cpp和.h文件添加进工程目录,就完成了。
接下来需要在工程里添加MQTT的.cpp和.h文件,查看一下要添加的文件
在.pro里面添加:
执行qmake,重新构建工程,有报错的地方就修改一下,不报错就算移植完成了
程序与云平台的通信格式采用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);
}
功能实现部分槽函数
云端消息接收及显示
/*接收到云端消息*/
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();
}