在鸿蒙系统上使用MQTT编程

百家 作者:51CTO技术栈 2020-11-19 19:01:12

我们使用的是 Paho MQTT 软件包,这里介绍一下怎么使用 MQTT 协议编程。


关于鸿蒙系统的 MQTT 移植好的软件包,相关 Github 链接如下:

https://gitee.com/qidiyun/harmony_mqtt

这里提供一个简单的编程示例:这里我们使用 MQTTClient 编程模型,他支持多任务多线程,非常适合用在鸿蒙系统上。


01

网络初始化


这里定义一个 Network 结构体,然后指定我们的 MQTT 服务器的 IP 和端口号。
Network n;
   //初始化结构体
 NetworkInit(&n);
 //连接到指定的MQTT服务器IP、端口号
 NetworkConnect(&n, “XXX.XXX.XXX.XXX”, XXXX);


02

设置 MQTT 缓存和启动 MQTT 线程


我们这里使用的是 MQTT 线程功能:
 MQTTClientInit(&c, &n, 1000, buf, 100, readbuf, 100);
 MQTTStartTask(&c);


03

设置 MQTT 相关参数


接下来我们设置 MQTT 的相关参数,包括版本号、客户端 ID、账户密码等:
MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 
 data.willFlag = 0;
 //MQTT版本为 v3
 data.MQTTVersion = 3;
 //设置客户端ID
 data.clientID.cstring = opts.clientid;
 //设置客户端账户
 data.username.cstring = opts.username;
 //设置客户端密码
 data.password.cstring = opts.password;
 data.keepAliveInterval = 10;
 data.cleansession = 1;

 //连接到MQTT服务器
 rc = MQTTConnect(&c, &data);


04

订阅主题和接收消息


订阅主题可以使用如下函数:
MQTTSubscribe(&ctopicopts.qosmessageArrived);

它的函数原型如下:
DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler);

其中:

  • MQTTClient* c :我们前面定义的 MQTTClient 结构体。

  • const char* topicFilter:订阅的主题。

  • messageHandler messageHandler :接收到主题信息后的回调处理函数。


例如上面我们的回调函数是  messageArrived ,它的原型如下:
void messageArrived(MessageData* md)
{
 MQTTMessage* message = md->message;
 //打印接收到的消息的长度、和消息内容
 printf("%.*s", (int)message->payloadlen, (char*)message->payload);
}


05

发送消息


发送消息也比较简单,我们只需要设置好我们的主题和消息内容即可:
memset(&pubmsg, '\0'sizeof(pubmsg));
 //消息内容为 hello harmonyOS !
   pubmsg.payload = (void*)"hello harmonyOS !";
 //消息长度
   pubmsg.payloadlen = strlen((char*)pubmsg.payload);
   pubmsg.qos = QOS0;
   pubmsg.retained = 0;
   pubmsg.dup = 0;

 //推送消息,主题为 pubtest
 MQTTPublish(&c, "pubtest", &pubmsg);

完整源码如下:
#include <stdio.h>

#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include <unistd.h>
#include "hi_wifi_api.h"
//#include "wifi_sta.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"

#include "lwip/sockets.h"

#include "MQTTClient.h"

/**
 * MQTT URI farmat:
 * domain mode
 * tcp://iot.eclipse.org:1883
 *
 * ipv4 mode
 * tcp://192.168.10.1:1883
 * ssl://192.168.10.1:1884
 *
 * ipv6 mode
 * tcp://[fe80::20c:29ff:fe9a:a07e]:1883
 * ssl://[fe80::20c:29ff:fe9a:a07e]:1884
 */

#define MQTT_URI                "tcp://106.13.62.194:1883"

struct opts_struct
{

    char* clientid;
    int nodelimiter;
    char* delimiter;
    enum QoS qos;
    char* username;
    char* password;
    char* host;
    int port;
    int showtopics;
} opts =
{
    (char*)"stdout-subscriber"0, (char*)"\n", QOS2, NULLNULL, (char*)"106.13.62.194"18831
};


void messageArrived(MessageData* md)
{
    MQTTMessage* message = md->message;

    if (opts.showtopics)
        printf("%.*s\t", md->topicName->lenstring.len, md->topicName->lenstring.data);
    if (opts.nodelimiter)
        printf("%.*s", (int)message->payloadlen, (char*)message->payload);
    else
        printf("%.*s%s", (int)message->payloadlen, (char*)message->payload, opts.delimiter);
    //fflush(stdout);
}


unsigned char buf[100];
unsigned char readbuf[100];

int mqtt_test(void)
{
    int rc = 0;

    MQTTMessage pubmsg;


    char* topic = "test";

    if (strchr(topic, '#') || strchr(topic, '+'))
        opts.showtopics = 1;
    if (opts.showtopics)
        printf("topic is %s\n", topic);

    Network n;
    MQTTClient c;

    NetworkInit(&n);
    NetworkConnect(&n, opts.host, opts.port);

    MQTTClientInit(&c, &n, 1000, buf, 100, readbuf, 100);
    MQTTStartTask(&c);

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       
    data.willFlag = 0;
    data.MQTTVersion = 3;
    data.clientID.cstring = opts.clientid;
    data.username.cstring = opts.username;
    data.password.cstring = opts.password;

    data.keepAliveInterval = 10;
    data.cleansession = 1;
    printf("Connecting to %s %d\n", opts.host, opts.port);

    rc = MQTTConnect(&c, &data);
    printf("Connected %d\n", rc);



    printf("Subscribing to %s\n", topic);
    rc = MQTTSubscribe(&c, topic, opts.qos, messageArrived);
    printf("Subscribed %d\n", rc);

    memset(&pubmsg, '\0'sizeof(pubmsg));
      pubmsg.payload = (void*)"hello harmonyOS !";
      pubmsg.payloadlen = strlen((char*)pubmsg.payload);
      pubmsg.qos = QOS0;
      pubmsg.retained = 0;
      pubmsg.dup = 0;



    while (1)
    {
        MQTTPublish(&c, "pubtest", &pubmsg);
        sleep(1);   
    }

    printf("Stopping\n");

    MQTTDisconnect(&c);
    NetworkDisconnect(&n);

    return 0;
}



送 福 利 啦

关注HarmonyOS技术社区,回复【鸿蒙】定制T恤(礼品不多,先到先得),还可以免费下载鸿蒙入门资料


关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接