【完全原创】QT写的阿里云物联网模拟器小工具,可以在windows上连接云平台


【背景】

还是之前的那个事情,找个物联网模拟器小工具实在是找不到了,只能自己抽空写个小工具了。qmqtt库已经安装好了,关于qmqtt协议的学习已经看的差不多了,然后就写了这个小工具。

【设计思路】

既然有了qmqtt库,那就实例化一个qmqtt的client,然后将里面的主要信号连接到槽函数,在槽函数里进行一系列相关的操作。当然,肯定需要一些用户交互的按钮、输入框什么的,大概的画个思路吧。

【过程】

1、实例化qmqtt的client,设置槽函数

    client = new QMQTT::Client();
    connect(client,SIGNAL(connected()),this,SLOT(doConnected()));
    connect(client,SIGNAL(disconnected()),this,SLOT(doDisconnected()));
    connect(client,SIGNAL(received(QMQTT::Message)),this,SLOT(doDataReceived(QMQTT::Message)));
    connect(client,SIGNAL(error(QMQTT::ClientError)),this,SLOT(doError(QMQTT::ClientError)));

 2、连接参数计算

这里是个关键点,最主要的就是如何生成连接需要的参数。这里有两个需要注意的问题:

第一、获取的字符串必须要转一下格式。具体如下所示:

    //配置MQTT连接参数
    client->setHostName(hostname.toLatin1());// toLatin1()将字符串转换为QByteArray,系统已经设置编码默认utf-8
    client->setPort(1883);
    client->setClientId(client_id.toLatin1());
    client->setUsername(username.toLatin1());
    client->setPassword(password.toLatin1());

第二、关于Hmacsha1签名算法

阿里云的用户密码需要用Hmacsha1算法进行计算,算法是公开的,QT官网也有:https://wiki.qt.io/HMAC-SHA1。大家可以去看看,我也是参照这个链接进行计算的。但是,重点在于一定要把最后的返回值格式改成Hex的,不能是qbase64,因为阿里云的密码是hex的,下面是修改之后的算法:

/**
 * @brief MainWindow::hmacSha1
 * hmacsha1算法,计算密码
 * @param key
 * @param baseString
 * @return
 */
QString MainWindow::hmacSha1(QByteArray key, QByteArray baseString)
{
    int blockSize = 64; // HMAC-SHA-1 block size, defined in SHA-1 standard
    if (key.length() > blockSize) { // if key is longer than block size (64), reduce key length with SHA-1 compression
        key = QCryptographicHash::hash(key, QCryptographicHash::Sha1);
    }

    QByteArray innerPadding(blockSize, char(0x36)); // initialize inner padding with char "6"
    QByteArray outerPadding(blockSize, char(0x5c)); // initialize outer padding with char "quot;

    for (int i = 0; i < key.length(); i++) {
        innerPadding[i] = innerPadding[i] ^ key.at(i); // XOR operation between every byte in key and innerpadding, of key length
        outerPadding[i] = outerPadding[i] ^ key.at(i); // XOR operation between every byte in key and outerpadding, of key length
    }

    QByteArray total = outerPadding;
    QByteArray part = innerPadding;
    part.append(baseString);
    total.append(QCryptographicHash::hash(part, QCryptographicHash::Sha1));
    QByteArray hashed = QCryptographicHash::hash(total, QCryptographicHash::Sha1);

    return hashed.toHex();//此处必须为tohex,因为阿里云的是hex
}

还有,把需要的参数按照阿里云的要求组合起来,计算所有需要的参数,这应该算是个小苦力活了。没啥说的。

3、连接成功

/**
 * @brief MainWindow::doConnected
 * 连接代理
 */
void MainWindow::doConnected()
{
    qDebug() << "doConnected !!!!!!!!!";
    QString currentTime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
    QString log = currentTime +"  连接成功!" + "\n";
    ui->te_log->append(log);
    ui->linkSta->setStyleSheet(ledGreen_Style_small);
    ui->pb_connect->setText("Disconnect");
    ui->publishBtn->setEnabled(true);
    ui->subscribeBtn->setEnabled(true);
    ui->unSubscribeBtn->setEnabled(true);
}

4、连接失败

/**
 * @brief MainWindow::doDisconnected
 * 断开连接
 */
void MainWindow::doDisconnected()
{
    qDebug() << "doDisconnected";
    paraEnFlag = 1;
    contrlPara();
    QString currentTime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
    QString log = currentTime +"  连接断开!" + "\n";
    ui->te_log->append(log);
    ui->linkSta->setStyleSheet(ledRed_Style_small);
    ui->pb_connect->setText("Connect");
    ui->publishBtn->setEnabled(false);
    ui->subscribeBtn->setEnabled(false);
    ui->unSubscribeBtn->setEnabled(false);
}

5、接收消息

/**
 * @brief MainWindow::doDataReceived
 * 接收消息
 * @param message
 */
void MainWindow::doDataReceived(Message message)
{
    QString currentTime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
    QString mes = currentTime + " " + QString::number(message.id())+ " | " + QString::number(message.qos())+ " | " +message.topic()+ " | " + message.payload() + "\n";
    ui->te_log->append(mes);

    qDebug() << "doDataReceived";
}

6、发布消息

/**
 * @brief MainWindow::on_publishBtn_clicked
 * 发布消息
 */
void MainWindow::on_publishBtn_clicked()
{
    qDebug() << "on_pushButton_clicked";
    QString currentTime = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss");
    QString topic = ui->le_pb_topic->text().trimmed();
    QString payload = ui->le_pu_payload->toPlainText();//text().trimmed();
    if(topic.isEmpty() || payload.isEmpty())
    {
        qDebug()<<"pub topic and payload is empty!"<<endl;
        QString log = currentTime + "  pub topic or payload is empty!" + "\n";
        ui->te_log->append(log);
        return;
    }
    QMQTT::Message message(136,topic,payload.toUtf8());
    client->publish(message);
    QString mes = currentTime +" "+ QString(message.id())+" "+QString(message.qos())+" "+message.topic()+" "+message.payload()+"\n";
    ui->te_log->append(mes);
}

嗯。。。大概就是这么多,其他的关于qmqtt库的使用,可以看我的上一个博文:https://blog.csdn.net/yimuta9538/article/details/104010393

最后,把完成的小工具分享给大家,不过大家也要体谅小弟的辛苦,互相理解。

进行下面的步骤进行下载,解压密码关注公众号“码代码”,发送“解压密码”获取:

方法一:CSDN下载,需要5积分,

https://download.csdn.net/download/yimuta9538/12109492

方法二:关注公众号“码代码”,获取百度下载连接

公众号发送“阿里云”,获取百度下载连接。

发布了17 篇原创文章 · 获赞 9 · 访问量 2328

猜你喜欢

转载自blog.csdn.net/yimuta9538/article/details/104019107