1、相关概念
- MQTT [1] 全名为Message Queuing Telemetry Transport,是一种基于TCP/IP协议上传输的轻量级通信协议,采用订阅、发布机制,订阅者只接收自己已经订阅的数据,非订阅数据则不接收,既保证了必要的数据的交换,又避免了无效数据造成的储存与处理
2、MQTT的操作过程
基于阿里云的MQTT数据传输,实现功能:
- STM32上报温度和灯的状态给阿里云服务器
- PC网页和手机APP从阿里云能够获取温度和灯的开关状态并显示
- 通过PC网页和手机APP能够控制STM32灯的状态
1:登录阿里云平台 - 产品 - 物联网 - 物联网平台 - 管理控制台 - 公共实例
2:创建产品 - 设备管理 - 产品 - 创建产品 -
名称 - EHOME0701
品类 - 标准品类 - 自己选
节点类型 - 直连设备
连网与数据 - 蜂窝
确认
3.创建设备 - 产品 - 管理产品 - 添加设备
Devicename - 自定义 - 英文
备注 - 无所谓
确认 - 完成
4:获取三元组:设备 - 查看 - 右上角(查看)
{
"ProductKey": "a1584e1xqTg",
"DeviceName": "jiajing",
"DeviceSecret": "17fee0bf423cd33d84b4c02c5cc10bd8"
}
5:阿里云服务器IP地址格式 ${ProductKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com
ip地址 - a1584e1xqTg.iot-as-mqtt.cn-shanghai.aliyuncs.com
端口号 - 1883
6:构造clientid:${DeviceName}|securemode=3,signmethod=hmacsha1|;
username:${DeviceName}&${ProductKey};
passwd :由加密对象和密钥,通过加密算法得到,生成网址:[]https://encode.chahuo.com/#google_vignette
由加密对象:clientId${DeviceName}deviceName${DeviceName}productKey${ProductKey}
密钥:${DeviceSecret}
加密算法:HMACSHA1
clientid: jiajing|securemode=3,signmethod=hmacsha1|
username: jiajing&a1584e1xqTg
passwd:
加密对象 : clientIdjiajingdeviceNamejiajingproductKeya1584e1xqTg
秘钥 : 17fee0bf423cd33d84b4c02c5cc10bd8
加密算法 - HMACSHA1
密码 : 074be22cf90f6fd29ea7bc9ad89082ea77091e99
7.订阅主题/发布主题
订阅主题 - 客户端表达对某个特定主题的消息感兴趣
发布主题 - 客户端向某个特定主题发送消息的行为
进入物联网平台-产品 - 查看 - topic类列表 - 物模型通信topic
发布主题:/sys/a1584e1xqTg/${deviceName}/thing/event/property/post
订阅主题:/sys/a1584e1xqTg/${deviceName}/thing/service/property/set
8.功能的添加
温度/报警家庭健康设备
温度测量 + 报警
led0 / led1 / 温度传感器
步骤:
1.产品 - 查看 - 功能定义 - 编辑草稿 - 添加自定义功能
2.发布上线
3.查看
设备 - 选择目标设备 - 物模型数据
9.对设备的调试
一个标签页 - 物模型数据
另一个标签页 - 调试
步骤 - 设备管理 - 设备模拟器 - 选中产品/设备 - 启动设备模拟器 - 3.1.1
属性上报 - 卧室灯/餐厅灯/当前温度 发送指令
3、MQTT协议
- 报文格式
Fixed header 固定报头,所有控制报文都包含
Variable header 可变报头,部分控制报文包含
Payload 有效载荷,部分控制报文包含
3.1 固定报文
每个MQTT控制报文都包含一个固定报文,格式为:
控制报文的类型
标志位
剩余长度
表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。
3.2 连接报文
客户端首次向服务端发送的第一个报文。由3部分组成,由固定报头、可变报头和剩余长度组成
-
固定包头格式:10 ?
-
可变报头:00 04 4D 51 54 54 04 C2 00 64
按下列次序包含四个字段:协议名(Protocol Name),协议级别(ProtocolLevel),连接标志(Connect Flags)和保持连接(Keep Alive)。
协议级别:对于3.1.1版协议,协议级别字段的值是4(0x04)
连接标志:
保持连接:
- 有效载荷
CONNECT 报文的有效载荷(payload)包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码
clientid: xx xx clientid内容 (xx xx 表示clienttid的长度)
clientid: jiajing|securemode=3,signmethod=hmacsha1|
clientid: 00 29 6A 69 61 6A 69 6E 67 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C
username: xx xx username内容 (xx xx 表示username的长度)
username: jiajing&a1584e1xqTg
username: 00 13 6A 69 61 6A 69 6E 67 26 61 31 35 38 34 65 31 78 71 54 67
passwd: xx xx passwd内容 (xx xx 表示passwd的长度)
passwd: 074be22cf90f6fd29ea7bc9ad89082ea77091e99
passwd: 00 28 30 37 34 62 65 32 32 63 66 39 30 66 36 66 64 32 39 65 61 37 62 63 39 61 64 38 39 30 38 32 65 61 37 37 30 39 31 65 39 39
所以有效载荷为:
00 29 6A 69 61 6A 69 6E 67 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 00 13 6A 69 61 6A 69 6E 67 26 61 31 35 38 34 65 31 78 71 54 67 00 28 30 37 34 62 65 32 32 63 66 39 30 66 36 66 64 32 39 65 61 37 62 63 39 61 64 38 39 30 38 32 65 61 37 37 30 39 31 65 39 39
- 剩余长度
剩余长度=可变报头的长度+有效载荷的长度= 116,所以固定报头为:10 74 - 连接报文为:
固定报头 可变报头 有效载荷
10 74 00 04 4D 51 54 54 04 C2 00 64 00 29 6A 69 61 6A 69 6E 67 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 00 13 6A 69 61 6A 69 6E 67 26 61 31 35 38 34 65 31 78 71 54 67 00 28 30 37 34 62 65 32 32 63 66 39 30 66 36 66 64 32 39 65 61 37 62 63 39 61 64 38 39 30 38 32 65 61 37 37 30 39 31 65 39 39
演示
3.3 确认连接请求
服务端发送 CONNACK 报文响应从客户端收到的 CONNECT 报文。服务端发送给客户端的第一个报文必须是 CONNACK
-
固定报头:20 02
-
可变报头:00
sp:当前会话标志,这里设置为0
连接返回码:根据实际情况返回
上文中的返回码为00,即代表成功
3.4 构造订阅报文
客户端向服务端发送 SUBSCRIBE 报文用于创建一个或多个订阅。每个订阅注册客户端关心的一个或多个主题。
-
固定报文: 82 ?
-
可变报文:00 0A
-
有效载荷
即
有效载荷:xx xx 订阅主题 00 (xx xx)订阅主题的长度
订阅主题:/sys/a1584e1xqTg/jiajing/thing/service/property/set
有效载荷:00 33 2F 73 79 73 2F 61 31 35 38 34 65 31 78 71 54 67 2F 6A 69 61 6A 69 6E 67 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 00
- 剩余长度:有效载荷+可变报头 56 0x38
即订阅报文为
82 38 00 0A 00 33 2F 73 79 73 2F 61 31 35 38 34 65 31 78 71 54 67 2F 6A 69 61 6A 69 6E 67 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 00
3.5 订阅确认报文
服务端发送 SUBACK 报文给客户端,用于确认它已收到并且正在处理 SUBSCRIBE 报文
-
固定报文:90 ?
-
可变报文:
可变报头包含等待确认的 SUBSCRIBE 报文的报文标识符,即和构造订阅报文里面的可变报文保持一致 -
有效载荷:
有效载荷包含一个返回码清单。每个返回码对应等待确认的 SUBSCRIBE 报文中的一个主题过滤器。
利用阿里物联网平台给网络调试助手客户端下发一个属性设置消息(例如:开灯),
上文中返回的确认订阅报文为:90 03 00 0A 016
回传报文:
30 9B 01 00 33 2F 73 79 73 2F 61 31 35 38 34 65 31 78 71 54 67 2F 6A 69 61 6A 69 6E 67 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 73 65 72 76 69 63 65 2E 70 72 6F 70 65 72 74 79 2E 73 65 74 22 2C 22 69 64 22 3A 22 39 36 39 31 37 34 39 31 36 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 62 65 64 5F 72 6F 6F 6D 5F 6C 65 64 22 3A 31 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D
拆分
30 9B 01 // 固定报头
00 33 // 可变报头中主题的长度
2F 73 79 73 2F 61 31 35 38 34 65 31 78 71 54 67 2F 6A 69 61 6A 69 6E 67 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 // 可变报文的主题名 /sys/a1584e1xqTg/jiajing/thing/service/property/set
7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 73 65 72 76 69 63 65 2E 70 72 6F 70 65 72 74 79 2E 73 65 74 22 2C 22 69 64 22 3A 22 39 36 39 31 37 34 39 31 36 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 62 65 64 5F 72 6F 6F 6D 5F 6C 65 64 22 3A 31 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D // 有效载荷{"method":"thing.service.property.set","id":"969174916","params":{"bed_room_led":1},"version":"1.0.0"}
3.6 发布报文
PUBLISH 控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息。
-
固定报头:30 ?
-
可变报文
可变报头按顺序包含主题名和报文标识符
发布主题:/sys/a1584e1xqTg/jiajing/thing/event/property/post
发布主题:2F 73 79 73 2F 61 31 35 38 34 65 31 78 71 54 67 2F 6A 69 61 6A 69 6E 67 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74
可变报文:长度 发布主题
可变报文:00 32 2F 73 79 73 2F 61 31 35 38 34 65 31 78 71 54 67 2F 6A 69 61 6A 69 6E 67 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74
- 有效载荷
有效载荷:{"method":"thing.event.property.post","id":"2004893243","params":{"bed_room_led":0},"version":"1.0.0"}
有效载荷:7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 22 69 64 22 3A 22 32 30 30 34 38 39 33 32 34 33 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 62 65 64 5F 72 6F 6F 6D 5F 6C 65 64 22 3A 30 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D
即报文为:
剩余长度:可变报文+有效载荷 - 148 - 0x94 151
当剩余剩余长度大于127时,后面添加一个0x01
30 9A 01 00 32 2F 73 79 73 2F 61 31 35 38 34 65 31 78 71 54 67 2F 6A 69 61 6A 69 6E 67 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74 7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 22 69 64 22 3A 22 32 30 30 34 38 39 33 32 34 33 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 62 65 64 5F 72 6F 6F 6D 5F 6C 65 64 22 3A 30 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D
回复内容:
30 AB 01
00 38
2F 73 79 73 2F 61 31 35 38 34 65 31 78 71 54 67 2F 6A 69 61 6A 69 6E 67 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74 5F 72 65 70 6C 79 // /sys/a1584e1xqTg/jiajing/thing/event/property/post_reply
7B 22 63 6F 64 65 22 3A 32 30 30 2C 22 64 61 74 61 22 3A 7B 7D 2C 22 69 64 22 3A 22 32 30 30 34 38 39 33 32 34 33 22 2C 22 6D 65 73 73 61 67 65 22 3A 22 73 75 63 63 65 73 73 22 2C 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 22 7D //{"code":200,"data":{},"id":"2004893243","message":"success","method":"thing.event.property.post","version":"1.0"}