OpenHarmony开发之MQTT讲解

相信MQTT这个名称大家都不陌生,物联网的开发必然会遇到MQTT相关知识的应用。那么什么是MQTT?它有什么特点?它能解决什么问题?它是如何工作的?OpenAtom OpenHarmony(以下简称“OpenHarmony”)的物联网开发者要如何使用及验证MQTT功能?接下来的内容将一一为你解答。下图为MQTT通信模型。

什么是MQTT

MQTT(Message Queuing Telemetry Transport消息队列遥测传输)是一种物联网协议,是一种客户端与服务端架构的发布/订阅模式的消息传输协议,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网开发的轻量级传输协议。MQTT协议针对低带宽网络,低计算能力的设备,做了特殊的优化,使得其能适应各种物联网应用场景。目前它已广泛应用于车联网、智能家居、即时聊天应用和工业互联网等领域。

MQTT的基本原理

在MQTT通讯中,有两个最为重要的角色。它们分别是服务端和客户端。

MQTT服务端

MQTT服务端通常是一台服务器。它是MQTT信息传输的枢纽,负责将MQTT客户端发送来的信息传递给MQTT客户端。MQTT服务端还负责管理MQTT客户端。确保客户端之间的通讯顺畅,保证MQTT消息得以正确接收和准确投递。

MQTT客户端

MQTT客户端可以向服务端发布信息,也可以从服务端收取信息。我们把客户端发送信息的行为称为“发布”信息。而客户端要想从服务端收取信息,则首先要向服务端“订阅”信息。“订阅”信息这一操作很像我们在视频网站订阅某一部电视剧。当这部电视剧上新后,视频网站会向订阅了该剧的用户发送信息,告诉他们有新剧上线了。

MQTT主题

刚刚我们在讲解MQTT客户端订阅信息时,使用了用户在视频网站订阅电视剧这个例子。在MQTT通讯中,客户端所订阅的肯定不是一部部电视剧,而是一个个“主题”。MQTT服务端在管理MQTT信息通讯时,就是使用“主题”来控制的。为了便于您更好理解服务端是如何通过主题来控制客户端之间的信息通讯,我们来看看下图示例:

以上图示中一共有三个MQTT客户端。它们分别是汽车、手机和电脑。在管理MQTT通讯时,MQTT服务端使用了“主题”来对信息进行管理。比如上图所示,假设我们需要利用手机和电脑获取汽车的速度,那么我们首先要利用电脑和手机向MQTT服务器订阅主题“汽车速度”。接下来,当汽车客户端向服务端的“汽车速度”主题发布信息后,服务端就会首先检查以下都有哪些客户端订阅了“汽车速度”这一主题的信息。当它发现订阅了该主题的客户端有一个手机和一台电脑,于是服务端就会将刚刚收到的“汽车速度”信息转发给订阅了该主题的手机和电脑客户端。

以上实例中,汽车是“汽车速度”主题的发布者,而手机和电脑则是该主题的订阅者。

值得注意的是,MQTT客户端在通讯时,往往角色不是单一的。它既可以作为信息发布者也可以同时作为信息订阅者。如下图所示:

上图中的所有客户端都是围绕“空调温度”这一主题进行通讯的。对于“空调温度”这一主题,手机和电脑客户端成为了MQTT信息的发布者而汽车则成为了MQTT信息的订阅者(接收者)。

可以看到,针对不同的主题,MQTT客户端可以切换自己的角色。它们可能对主题A来说是信息发布者,但是对于主题B就成了信息订阅者。

MQTT客户端开发流程

以下采用的Paho MQTT样例,简要说明MQTT的开发流程。

样例代码在OpenHarmony源码目录/device/board/bearpi/bearpi_hm_nano/app/D5_iot_mqtt,源码下载路径参考文章末尾。开发应用主要涉及以下几个API应用:

MQTT的流程主要由四个步骤组成:

1、创建客户端对象;
2、连接服务器;
3、订阅主题;
4、发布主题。

//订阅的回调函数
void messageArrived(MessageData *data)
{
    printf("Message arrived on topic %.*s: %.*s\n", data->topicName->lenstring.len,
        data->topicName->lenstring.data, data->message->payloadlen, data->message->payload);
}
//主流程函数
static void MQTTDemoTask(void)
{
    WifiConnect("BearPi", "123456789");
    printf("Starting ...\n");
    int rc, count = 0;
    MQTTClient client;
 
    NetworkInit(&network);
    printf("NetworkConnect  ...\n");
 
    NetworkConnect(&network, MQTT_SERVERIP, MQTT_SERVERPORT);//本地电脑作为消息代理 此处为电脑IP
    printf("MQTTClientInit  ...\n");
    //1-------------创建客户端对象
    MQTTClientInit(&client, &network, MQTT_CMD_TIMEOUT_MS, sendBuf, sizeof(sendBuf), readBuf, sizeof(readBuf));
 
    MQTTString clientId = MQTTString_initializer;
    clientId.cstring = "bearpi";
 
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.clientID = clientId;
    data.willFlag = 0;
    data.MQTTVersion = MQTT_VERSION;
    data.keepAliveInterval = MQTT_KEEP_ALIVE_MS;
    data.cleansession = 1;
 
    printf("MQTTConnect  ...\n");
    //2-------------连接服务端
    rc = MQTTConnect(&client, &data);
    if (rc != 0) {
        printf("MQTTConnect: %d\n", rc);
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
        osDelay(MQTT_DELAY_2S);
    }
 
    printf("MQTTSubscribe  ...\n");
    //3-------------订阅主题substopic
    rc = MQTTSubscribe(&client, "substopic", MQTT_QOS, messageArrived);
    if (rc != 0) {
        printf("MQTTSubscribe: %d\n", rc);
        osDelay(MQTT_DELAY_2S);
    }
    while (++count) {
        MQTTMessage message;
        char payload[30];
 
        message.qos = MQTT_QOS;
        message.retained = 0;
        message.payload = payload;
        (void)sprintf_s(payload, sizeof(payload), "message number %d", count);
        message.payloadlen = strlen(payload);
    //4------------发布pubtopic主题
        if ((rc = MQTTPublish(&client, "pubtopic", &message)) != 0) {
            printf("Return code from MQTT publish is %d\n", rc);
            NetworkDisconnect(&network);
            MQTTDisconnect(&client);
        }
        osDelay(MQTT_DELAY_500_MS);
    }
}

开发板MQTT客户端代码一直循环发送主题为pubtopic的信息,信息内容为(“message number %d”, count),每次信息count++;

同时开发板客户端也在订阅主题为substopic的信息,一旦接收到substopic信息就会调用回调函数,串口打印出substopic主题的内容。

MQTT实操验证

如何验证MQTT客户端代码是否正常?验证过程主要涉及以下几点:

1、下载消息代理Mosquitto软件,并配置Mosquitto;

2、下载EclipsePahoMQTT工具,并用该工具创建一个客户端,我们简称客户A;

3、修改客户端MQTT代码相关配置,与第一步配置Mosquitto相匹配,客户端我们简称客户B。

简要说明下本次验证中涉及的各个模块的作用:

1、消息代理Mosquitto:可以理解为它就是MQTT服务器,所有客户端的消息(发布/订阅)都是与它通信;它负责接收及分发所有信息;

2、EclipsePahoMQTT工具创建的客户端A:我们用来与创建的客户端B进行信息交互(发布/订阅)。

详细细节:

1、下载消息代理Mosquitto软件,并配置Mosquitto:

(1)点击下载网址(https://mosquitto.org/download/),选择合适的版本,并安装(记录安装路径);

(2)安装好后,配置Mosquitto,并开启Mosquitto服务:

在Mosquitto软件的安装路径找到mosquitto.conf,打开并作如下修改:

192.168.120.137是本电脑的IP;1883指本次用来验证的服务端口号(本电脑IP192.168.120.137可以有多个服务端口);allow_anonymous true指允许客户端匿名登录;

修改配置后,在安装目录打开命令窗口,输入.\mosquitto -c .\mosquitto.conf -v。服务器启动成功后,如下图显示mosquitto version 2.0.11 starting.

2、下载EclipsePahoMQTT工具,创建客户端A,并连接服务器:

3、修改客户端MQTT代码相关配置,与第一步配置Mosquitto相匹配,客户端我们简称客户B:

修改连接端代码:

NetworkConnect(&network, 192.168.120.137, 1883);//本地电脑作为消息代理 此处为电脑IP Mosquitto相匹配

4、烧录代码,并操作(发布\订阅)通信:

客户端B做了两件事情:1、一直循环发送主题为pubtopic的信息,信息内容是(“message number %d”, count);2、订阅了主题为substopic的信息,一旦服务器有该主题信息就会发送给客户端B,客户端B会把substopic的内容打印。

客户端A也做了两件事:1、订阅主题为pubtopic的信息;2、发布一条主题为substopic的信息,内容为“Hello OpenHarmony!”。

结合客户端B(开发板)部分代码:

printf("Starting ...\n");
NetworkInit(&network);
printf("NetworkConnect  ...\n");
NetworkConnect(&network, MQTT_SERVERIP, MQTT_SERVERPORT);//本地电脑作
printf("MQTTClientInit  ...\n");
//1-------------创建客户端对象
MQTTClientInit(&client, &network, MQTT_CMD_TIMEOUT_MS, sendBuf, sizeof(sendBuf), readBuf, sizeof(readBuf));
 
printf("MQTTConnect  ...\n");
//2-------------连接服务端
rc = MQTTConnect(&client, &data);
     
printf("MQTTSubscribe  ...\n");
//3-------------订阅主题substopic
rc = MQTTSubscribe(&client, "substopic", MQTT_QOS, messageArrived);
(void)sprintf_s(payload, sizeof(payload), "message number %d", count);
 //4------------循环发布pubtopic主题 内容为message number+connt的计数值
 MQTTPublish(&client, "pubtopic", &message)
//订阅的回调函数输出以下内容
printf("Message arrived on topic %.*s: %.*s\n", data->topicName->lenstring.len,
        data->topicName->lenstring.data, data->message->payloadlen, data->message->payload);

客户B:开发板烧录好代码后,电脑串口工具连接开发板,会有连接MQTT及订阅的信息(参照以上代码),如下图:

客户A:显示如下图:

总结

本文从讲解MQTT它是什么?原理是什么?到MQTT的应用开发(API函数接口调用例程),再到MQTT的验证(Mosquitto软件及EclipsePahoMQTT工具的使用)三个方面介绍了MQTT。希望通过本文介绍让大家对MQTT有个感性认识。

为了帮助到大家能够更有效的学习OpenHarmony 开发的内容,下面特别准备了一些相关的参考学习资料:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/634900.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

10最佳iPhone数据恢复软件评论

您还在寻找最好的iPhone数据恢复软件吗? 似乎我们在iPhone上放置了越来越多与日常生活和工作有关的重要事情。照片可以保持珍贵的时刻,联系人可以保持联系,录音,备忘录和日历可以作为提醒,视频和歌曲可以娱乐&#xf…

基于Java的推箱子游戏设计与实现(论文 + 源码)

【免费】关于基于JAVA的推箱子游戏.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89325018 基于Java的推箱子游戏设计与实现 摘 要 社会在进步,人们生活质量也在日益提高。高强度的压力也接踵而来。社会中急需出现新的有效方式来缓解人们的压力。…

NDI入门教程二

一、移植到RK: 编译相关: ndi本身没有什么好移植编译的,本身提供的就是so库。但是ndi依赖其它第三方开源库: avahi; dbus; expat; libcap; libdameon。因为编译这些开源库的服务器也需要安装一些插件所以在自己虚拟机Ubuntu20.04…

notepad++ 批量转所有文件编码格式为UTF-8

1、安装notepad及PythonScript_3.0.18.0插件 建议两者都保持默认路径安装x64版本: 阿里云盘分享https://www.alipan.com/s/xVUDpY8v5QL安装好后如下图: 2、new Script,新建脚本,文件名为ConvertEncoding 3、自动打开脚本&#xff…

Jenkins 动态salve简单配置连接 EKS

安装Jenkins helm repo add jenkins https://charts.jenkins.io helm repo update # 当前版本 jenkins-5.1.18.tgz瘦身后的 values.yaml # grep -Ev ^\s*#|^$ values.yaml nameOverride: fullnameOverride: namespaceOverride: clusterZone: "cluster.local" kubern…

(Oracle)SQL优化基础(三):看懂执行计划顺序

往期内容: (Oracle)SQL优化基础(一):获取执行计划 (Oracle)SQL优化基础(二):统计信息 获取到执行计划后,对于新手朋友来讲可能不知道…

火箭升空AR虚拟三维仿真演示满足客户的多样化场景需求

在航空工业的协同研发领域,航空AR工业装配系统公司凭借前沿的AR增强现实技术,正引领一场革新。通过将虚拟信息无缝融入实际环境中,我们为工程师、设计师和技术专家提供了前所未有的共享和审查三维模型的能力,极大地提升了研发效率…

【华为】BFD与静态路由和RIP联用

【华为】BFD与静态路由和RIP联用 实验需求配置AR1AR2AR3AR4效果抓包查看 实验需求 如上图组网所示,在R1上配置到达R4的Loopback0。 4.4.4.4/32网段的浮动静态路由,正常情况下通过R3访问R4。 当R3故障时,自动选路通过R2访问R4的Loopback0;在R…

企业文件加密软件推荐:迅软DSE加密软件你用了吗?

一、挑选企业文件加密软件需考虑的因素? 1、安全性:软件应采用业界认可的强加密算法,以确保数据的安全性。 迅软特有的256位高强度加密算法,从根本上阻止一切破解的可能性。 2、易用性:软件应该易于部署和管理&…

如何停止 iPad 和 iPhone 之间共享短信,独立接收和发送消息

概括 在当今高度互联的数字世界中,Apple 设备之间的无缝连接性提供了极大的便利,尤其是在消息同步方面。iPhone 和 iPad 用户通常可以享受到设备间短信的自动同步功能,这意味着无论是在哪个设备上,用户都可以接收和回复消息。然而…

游戏联运的挑战与核心关键点

​游戏联运一个看似充满机遇与挑战的行业,吸引了很多创业者的加入。然而,真正踏入这个行业后,许多人会发现,手游代理并非想象中的那么简单。今天,溪谷软件就来和大家聊聊游戏联运是怎么做的,需要注意什么。…

react中的useEffect()的使用

useEffect()是react中的hook函数,作用是用于创建由渲染本身引起的操作,而不是事件的触发,比如Ajax请求,DOM的更改 首先useEffect()是个函数,接受两个参数,第一个参数是一个方法,第二个参数是数…

《计算机体系结构》期末考试复习笔记(一)试卷手写笔记(超重点)

一、MIPS 执行速率执行时间有效CPI【第1题】 二、Amdahl定律 - 性能加速比SP【第2题,第3题,第4题】 (百分比f 倍数r ) 三、哈夫曼编码 2-4扩展码【第5题】 四、互连函数【第9题】 就是每生成一个根节点, 就从小到大重新排…

后量子密码解决方案

什么是后量子密码学 (PQC),为什么准备工作如此重要? 量子计算正在迅速发展;用不了多久,量子网络攻击就会成为可能。量子网络攻击将能够在几分钟内瘫痪大型网络。我们今天赖以保护我们的连接和交易的一切都将受到量子计算机的威胁,危及所有密…

【618狂欢】五款必抢好物!爆款数码好物让你轻松get新潮流!

随着科技的飞速发展,数码产品已经成为我们生活中不可或缺的一部分。它们不仅为我们提供了便捷的生活体验,更成为了我们展示个性和追求潮流的重要载体。而在每年的618购物狂欢节,各大电商平台都会推出众多优惠活动,让我们有机会以更…

Linux——进程信号

目录 一、信号的理解 二、信号的种类 2.1 标准信号 (1-31) 2.2 实时信号 (通常是34及以上) 三、信号的产生 3.1 用户通过终端产生信号 3.1.1 signal 函数 3.1.2 demo 测试 3.1.3 demo 现象 3.2 通过系统函数产生信号 3.2.1 demo 测试 3.3 由软件条件产生信号 3.3.1…

访问列表元素

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中,如果想将列表的内容输出也比较简单,可以直接使用print()函数即可。例如,创建一个名称为untitle的列表…

JAVA开发 基础Jaccard来计算两个字符串之间的重复率

计算两个字符串之间的重复率 Jaccard实现代码基于最长公共子序列来计算两个字符串之间的重复率 Jaccard Jaccard方法,也称为Jaccard相似度或Jaccard相似系数,是一种用于衡量两个集合相似程度的指标。其逻辑基于集合之间的交集与并集的关系来衡量它们的相…

Linux bc命令(bc指令)(基本计算器)(任意精度计算语言:支持浮点数运算、变量赋值和自定义函数等)

文章目录 bc命令文档英文中文 Linux bc 命令详解bc 命令的基本用法启动 bc 环境进行基本计算退出 bc bc 中的数学功能执行高级数学计算平方根和指数函数对数函数 处理精度问题 变量和数组变量赋值和使用数组的使用 创建和使用自定义函数 bc 命令的高级用法在脚本中使用 bc基本脚…

注解大全更新中~

Slf4j 是什么:Slf4j 是 Lombok 提供的一种注解,用于在类中自动生成一个名为 log 的日志对象。通过使用 Slf4j 注解,可以方便地在代码中使用日志功能,而无需手动创建和初始化日志对象。 怎么用: 1.导入依赖的包lombok…