Author:果果小师弟 电子信息专业在读研究生
有一点思考,有一点想法,有一点理性!
定个小小目标,努力成为习惯!在最美的年华遇见更好的自己!



发布消息和发布确认


  发布消息的单词为publish。PUBLISH 控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息。我们这里的Qos等级为:00。

一、发布消息

1.服务端向客户端传输一个应用消息

1.1固定报头

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_服务端

1.2.可变报头

  发布消息中的可变报头不包含报文标识符,只包含主题名Topic Name。主题名(Topic Name)用于识别有效载荷数据应该被发布到哪一个信息通道。名 必须是 PUBLISH 报文可变报头的第一个字段。只有当 QoS 等级是 1 或 2 时,报文标识符(Packet Identifier)字段才能出现在 PUBLISH 报文中。我们这里设置的 QoS 等级为0,所以报文标识符不会出现在 PUBLISH 报文中。

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_数据_02

主题名:/sys/a10zwkUxQUS/LY-1/thing/service/property/set

相应的16进制:

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_数据_03

  • 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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 共48个字节(0x30)
    也就是00 302F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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

1.固定报头为:30 ??

2.可变报头为:00 30 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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

最终为:

  • 30 ??00 302F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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

1.3.有效载荷

  有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的。有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度。包含零长度有效载荷的 PUBLISH 报文是合法的。

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_JSON_04

  有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的—JSON。这个JSON的内容就是服务端要发送给客户端的数据。

  现在就需要得到有效载荷:有效载荷我们通过服务端下发给客户端,操作如下:(首先要connect设备)

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_物联网_05STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_数据_06

  • 30 97 0100 30 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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 36 35 38 32 31 33 31 39 39 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 22 3A 30 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D

两个对比:

  • 30??00 302F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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
  • 3097 0100 302F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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 747B 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 36 35 38 32 31 33 31 39 39 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 22 3A 30 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D

解释:

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_数据_07

1.4.JSON

  JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。JSON是指JavaScript对象表示法(JavaScrip ObjectNotation)


{
"firstName":"John"
}

{ } : 大括号表示对象
" " : 双引号表示属性或者值
"firstName" :表示属性
"John" : 表示属性的具体信息
如:"temp":"10℃"

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_JSON_08

  下面表示有四个键:

{
"method":"thing.service.property.set",
"id":"658213199",
"params":{"PowerSwitch":0},
"version":"1.0.0"
}

  是不是很熟悉,就是让面发布消息的有效载荷。

2.客户端发送到服务端传输一个应用消息

2.1固定报头

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_服务端

2.2.可变报头

  发布消息中的可变报头不包含报文标识符,只包含主题名Topic Name。主题名(Topic Name)用于识别有效载荷数据应该被发布到哪一个信息通道。名 必须是 PUBLISH 报文可变报头的第一个字段。只有当 QoS 等级是 1 或 2 时,报文标识符(Packet Identifier)字段才能出现在 PUBLISH 报文中。我们这里设置的 QoS 等级为0,所以报文标识符不会出现在 PUBLISH 报文中。

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_服务端_10

主题名:/sys/a10zwkUxQUS/LY-1/thing/event/property/post

相应的16进制:

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_JSON_11

  • 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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 共47个字节(0x2F)
    也就是00 2F2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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

1.固定报头为:30 ??

2.可变报头为:00 27 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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

最终为:

  • 30 ??00 2F2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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

2.3.有效载荷

  有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的。有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度。包含零长度有效载荷的 PUBLISH 报文是合法的。

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_JSON_04

  有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的—JSON。这个JSON的内容就是服务端要发送给客户端的数据。

  现在就需要得到有效载荷:上面我们已经知道了服务端(阿里云服务器)下发到客户端(网络调试助手)的数据内容是:

{
"method":"thing.service.property.set",
"id":"658213199",
"params":{"PowerSwitch":0},
"version":"1.0.0"
}

那么同理我们可以得到客户端(网络调试助手)上发到服务端(阿里云服务器)得数据内容也就是有效载荷。

{
"method":"thing.event.property.post",
"id":"00000001",
"params":{"PowerSwitch":1,"CurrentHumidity":30,"CurrentTemperature":11.1},
"version":"1.0.0"
}

  服务端(阿里云服务器)下发到客户端(网络调试助手)中的数据内容中method是thing.service.property.set。那么客户端(网络调试助手)上发到服务端(阿里云服务器)中的数据内容method是thing.event.property.post。注意区别,id可以修改只要是8位数即可。params中的数据也可以随便改,因为我的设备有温湿度和开关,所以就加上了温湿度的信息。

  把他转换为16进制也就得到有效载荷的报文:

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_MQTT_13

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 30 30 30 30 30 30 30 31 22 2C 22 70 61
72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68
22 3A 31 2C 22 43 75 72 72 65 6E 74 48 75 6D 69 64 69 74
79 22 3A 33 30 2C 22 43 75 72 72 65 6E 74 54 65 6D 70 65
72 61 74 75 72 65 22 3A 31 31 2E 31 7D 2C 22 76 65 72 73
69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D
一共146个字节

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_MQTT_14

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_物联网_15

最终可得发布消息报文为:

  • 30C3 0100 2F2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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 747B 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 30 30 30 30 30 30 30 31 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 22 3A 31 2C 22 43 75 72 72 65 6E 74 48 75 6D 69 64 69 74 79 22 3A 33 30 2C 22 43 75 72 72 65 6E 74 54 65 6D 70 65 72 61 74 75 72 65 22 3A 31 31 2E 31 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D

现在我们通过网络调试助手来向阿里云服务端发布消息

 1.第一步向服务端发送connect报文确认是否连接成功。

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_数据_16

 2.在确认连接成功之后,向服务器发送发布消息报文

  • 30C3 0100 2F2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 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 747B 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 30 30 30 30 30 30 30 31 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 22 3A 31 2C 22 43 75 72 72 65 6E 74 48 75 6D 69 64 69 74 79 22 3A 33 30 2C 22 43 75 72 72 65 6E 74 54 65 6D 70 65 72 61 74 75 72 65 22 3A 31 31 2E 31 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D
    STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_JSON_17
    3.发布消息报文发送成功之后,调试助手的接收端不会显示任何数据且调试助手不会自动断开,同时在你的阿里云服务器的设备中可以看到刚刚上报给服务器的温湿度还有电源开关的数据。当然如果你发送的报文有错误的话,你的网络调试助手会自动断开而且设备端也不会显示任何数据。可以看到下图的温湿度信息显示正常,说明发布消息成功。
    STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_MQTT_18
    4.这样我们就通过网络调试助手上我们的阿里云服务器发送数据成功了。假如你有单片机和esp8266的话,就可以代替调试助手向服务器发送数据了。哈哈,是不是很奇妙啊!

3.剩余长度

 上面我们说剩余长度为195,转换成16进制就是C3 01。这好像跟我们用计算器算的不同啊!

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_JSON_19

这是MQTT中文手册中对剩余长度的描述和表示方法。

  • 1、剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码
  • 2、低7位有效位用于编码数据,最高有效位用于指示是否有更多的字节。剩余长度字段最大4个字节。

 显然195是大于128的是不能用单字节表示的。

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_JSON_20

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_服务端_21

二、发布确认

  上面我们说到我们发送发布消息的报文之后。网络调试助手没有返回信息,是因为我们的Qos等级设置的是00,而手册上说publish报文是对QoS 1等级的publish报文的响应,所以我们收不到是正常的。

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_JSON_22

STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_MQTT_23



STM32物联网实战教程(七)—MQTT协议发布消息和发布确认_MQTT_24