首先分享一篇华为云的官方指南:在线开发MQTT协议的智慧路灯_设备接入 IoTDA_最佳实践_设备接入_华为云
这篇文章很好地讲述了如何通过MQTT.fx的设备模拟器替代真实的设备,然后快速体验设备上报数据到物联网平台和远程下发控制命令到设备的全过程。但是MQTT.fx在这里屏蔽了太多MQTT协议的细节,我们只需要简简单单copy几条字符串,就可以完成CONNECT、PUBLIC等操作,这对于入门肯定是有好处的,但是如果想要从中学习MQTT协议,那就帮助不大了。所以在做完这个实验后,老师推荐我们使用网络调试助手通过MQTT协议接入到华为云物联网平台。所以在这里我也会用网络调试助手重现官方指南中所有的操作,在这个过程中熟悉了解MQTT报文的格式。
强烈建议先跟着华为云的官方指南先操作一遍!!!
软件:网络调试助手,附百度网盘链接:
链接:https://pan.baidu.com/s/19Nv_Q5jzwqVKQI_WczZCaQ
提取码:1i57
连接信息:
(1)根据官方指南,得到的ClientId、Username、Password
(2)成功注册设备后,获得的diviceId(不是这个截图里的,而是截图所代表的这一步完成之后,会自动收到一份txt,是那里面的)
(3)平台的对接地址
笔者的连接信息如下,建议大家可以用一个word文档把这些东西记下来,因为之后会用到:
ClientId:621e287fe68aa647c088f044_123456lzy_0_0_2022030114
Username:621e287fe68aa647c088f044_123456lzy
Password:0218f83bed7afa2be05c453fe79e585d3c2244fde7161f8b11b6ee8acf49c8fa
diviceId:621e287fe68aa647c088f044_123456lzy
平台对接地址:a1621c9400.iot-mqtts.cn-north-4.myhuaweicloud.com
(这些是笔者的连接信息哦,每个人连接信息都不相同)
一份MQTT报文由三个部分组成,分别是固定报头+可变报头+负载。我们先不去了解报文的每一个字段,每一个数字详细是什么含义,先来组装一个CONNECT报文。(以下出现的都是十六进制)
1、固定报头:10 +(可变报头和负载的总长度)
2、可变报头:00 04 4D 51 54 54 04 C2 00 64(00 64是Keep Alive的时长,可自行定义)
3、负载(这个部分一定要认真仔细)
先打开我们的网络调试助手,我们利用它来将字符串转化为十六进制,还能统计长度。要转化的字符串如下:
ClientId:621e287fe68aa647c088f044_123456lzy_0_0_2022030114
Username:621e287fe68aa647c088f044_123456lzy
Password:0218f83bed7afa2be05c453fe79e585d3c2244fde7161f8b11b6ee8acf49c8fa
先来转化ClientId,按照我的截图中的设置界面的各种选项:
将十六进制码复制过来:
36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 5F 30 5F 30 5F 32 30 32 32 30 33 30 31 31 34
然后在前面加上它的长度的十六进制码,右下角有十进制的长度,我们手算装换一下进制就行:
00 31 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 5F 30 5F 30 5F 32 30 32 32 30 33 30 31 31 34
(这里注意,长度的格式为00+长度,不要漏掉00)
依样画葫芦,得到Username和Password的十六进制串:
Username:
00 22 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79
Password:
00 40 30 32 31 38 66 38 33 62 65 64 37 61 66 61 32 62 65 30 35 63 34 35 33 66 65 37 39 65 35 38 35 64 33 63 32 32 34 34 66 64 65 37 31 36 31 66 38 62 31 31 62 36 65 65 38 61 63 66 34 39 63 38 66 61
再把三者连接起来,恭喜,CONNECT报文的负载就有了!
00 31 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 5F 30 5F 30 5F 32 30 32 32 30 33 30 31 31 34 00 22 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 00 40 30 32 31 38 66 38 33 62 65 64 37 61 66 61 32 62 65 30 35 63 34 35 33 66 65 37 39 65 35 38 35 64 33 63 32 32 34 34 66 64 65 37 31 36 31 66 38 62 31 31 62 36 65 65 38 61 63 66 34 39 63 38 66 61
然后我们把可变报头加到负载的前面:
00 04 4D 51 54 54 04 C2 00 64 00 31 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 5F 30 5F 30 5F 32 30 32 32 30 33 30 31 31 34 00 22 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 00 40 30 32 31 38 66 38 33 62 65 64 37 61 66 61 32 62 65 30 35 63 34 35 33 66 65 37 39 65 35 38 35 64 33 63 32 32 34 34 66 64 65 37 31 36 31 66 38 62 31 31 62 36 65 65 38 61 63 66 34 39 63 38 66 61
然后我们计算上面这一大串的长度,笔者这里为163,转化为十六进制就是A3,这里要注意一下了,如果大于128,A3后面要加01放进固定报头中,我这里是A3 01,so,最后的报文:
10 A3 01 00 04 4D 51 54 54 04 C2 00 64 00 31 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 5F 30 5F 30 5F 32 30 32 32 30 33 30 31 31 34 00 22 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 00 40 30 32 31 38 66 38 33 62 65 64 37 61 66 61 32 62 65 30 35 63 34 35 33 66 65 37 39 65 35 38 35 64 33 63 32 32 34 34 66 64 65 37 31 36 31 66 38 62 31 31 62 36 65 65 38 61 63 66 34 39 63 38 66 61
终于完成了,以上就是我们的CONNECT报文!现在我们来发送吧,上截图:
按照我的界面来配置界面,回复20 02 00 00 即为连接成功,回复其它的就是连接失败了,太久没有回复就是你滴十六进制码有问题,建议检查一下长度,有没有缺00,总长度后面是否要加01。连接成功后,在控制台找到所有设备。看到已经有了一个绿色的点,在线。
到此为止,我们已经完成了连接到平台的过程,发送的那一大串十六进制码,就是所谓的CONNECT报文。
接下来是PUBLISH报文,相信看到这里,你应该对报文有些许认识了吧,没有太多深奥的东西,就是一串十六进制的数字串,但是它的每个字节都有它的含义,少了一个字节,机器就辨认不出来。
如果你已经理解的话,那么只要知道结构,报文就可以自己整理出来了吧!
PUBLISH报文的结构:
(1)固定报头:30 +(可变报头+负载的总长度)
(2)可变报头:长度 + topic(华为云的指南有说明,topic实际上就是那个接口地址)
笔者的为:$oc/devices/{621e287fe68aa647c088f044_123456lzy}/sys/properties/report
(3)负载:依旧看华为云的指南,其实就是这段代码,复制过来,咱们把回车删掉,弄成一行。有一点要提,这个负载我们弄成十六进制后就不用在前面加长度了。
笔者的为:{"services": [{"service_id": "BasicData","properties": {"luminance": 40}}]}
(40是我改动的luminance的值,要验证的同学可以随意改一下)
最后的PUBLISH报文:
30 93 01 00 46 24 6F 63 2F 64 65 76 69 63 65 73 2F 7B 36 32 31 65 32 38 37 66 65 36 38 61 61 36 34 37 63 30 38 38 66 30 34 34 5F 31 32 33 34 35 36 6C 7A 79 7D 2F 73 79 73 2F 70 72 6F 70 65 72 74 69 65 73 2F 72 65 70 6F 72 74 7B 22 73 65 72 76 69 63 65 73 22 3A 20 5B 7B 22 73 65 72 76 69 63 65 5F 69 64 22 3A 20 22 42 61 73 69 63 44 61 74 61 22 2C 22 70 72 6F 70 65 72 74 69 65 73 22 3A 20 7B 22 6C 75 6D 69 6E 61 6E 63 65 22 3A 20 34 30 7D 7D 5D 7D
CONNECT后发送,上截图:
发送的PUBLISH报文虽然没有得到回复,但是我们刷新一下华为云的设备详情,变成了40,成功改变了luminance!
命令下发就更简单了,是平台给我们发命令,发送完CONNECT报文后,我们打开华为云平台的命令下发,点击确定:
在网络调试助手可以收到:
搞定!
写到这里我本来是想把MQTT的报文的各种结构、细节、资料什么的全部都copy贴过来的,如果上面的步骤都有好好过完的话,看懂MQTT协议应该是没有什么问题的了,但是随便一搜就能搜到的东西我也不好意思水字数了,CSDN上有很多人总结得比我更厉害(其实是因为我懒,哈哈哈)。我一直都是这样的观点,有基础才能看得懂,没基础,看别人写的经验、帖子,就是对着干巴巴的文字呲牙。实践之后形成感性的认识,才能更好接收理论上的知识。
最后,这是我写的第一篇文章,自己也是个新手,如果有写的不对的地方,希望大家不吝赐教!