目标
理解客户端在不同QoS值(0,1,2)下的所有主题发布流程协议(PUBLISH,PUBACK,PUBREC,PUBREL,PUBCOMP)
准备
参见 “MQTT 实践” ,“MQTT-Java 连接协议” 完成测试工程配置
实验代码
在代码中通过 message.setQos(2) 代码来设置QoS级别
/**
*
* 发布主题内容
*
*/
private static void publish(){
MemoryPersistence persistence = new MemoryPersistence()
try {
MqttConnectionOptions connOpts = new MqttConnectionOptions()
connOpts.setCleanStart(true)
connOpts.setKeepAliveInterval(0)
connOpts.setSessionExpiryInterval(60L)
MqttAsyncClient sampleClient = new MqttAsyncClient(MQTTConfigue.broker, MQTTConfigue.clientId, persistence)
IMqttToken token = sampleClient.connect(connOpts)
token.waitForCompletion()
MqttMessage message = new MqttMessage()
message.setQos(2)
byte [] content = "ShangHai".getBytes(StandardCharsets.UTF_8)
message.setPayload(content)
sampleClient.publish(MQTTConfigue.topic, message)
} catch(MqttException me) {
System.out.println("reason "+me.getReasonCode())
System.out.println("msg "+me.getMessage())
System.out.println("loc "+me.getLocalizedMessage())
System.out.println("cause "+me.getCause())
System.out.println("excep "+me)
me.printStackTrace()
}
}
QoS Level 下的协议流程概况
(S): 发送; (R): 接收
| QoS Level | 协议流程 |
|---|
| 0 | (S)PUBLISH |
| 1 | (S)PUBLISH -> (R)PUBACK |
| 2 | (S)PUBLISH -> (R)PUBREC -> (S)PUBREL -> (R)PUBCOMP |
QoS-0
实验日志
2023-08-31 08:50:55:148 Send 包类型:PUBLISH
2023-08-31 08:50:55:148 Send Message Header(二进制内容) : 00110000 00010100 00000000 00000110 01101000 01100001 01110010 01110110 01100101 01111001 00000011 00100011 00000000 00000001
2023-08-31 08:50:55:148 Send Message Header(字符串内容) : 0harvey#
2023-08-31 08:50:55:149 Send Message payload(二进制内容) : 01010011 01101000 01100001 01101110 01100111 01001000 01100001 01101001
2023-08-31 08:50:55:149 Send Message payload(字符串内容) : 内容长度=8,内容=ShangHai
PUBLISH协议
固定头
| 包类型 | 剩余长度 |
|---|
| 00110000 | 00010100 |
| 参见“3.3.1 PUBLISH Fixed Header” | 20个字节 |
可变头(12个字节)
Topic Name + Packet Identifier + Properties
| 00000000 | 00000110 | 01101000 | 01100001 | 01110010 | 01110110 | 01100101 | 01111001 | 00000011 | 00100011 | 00000000 | 00000001 |
|---|
| 主题 | 长度(6) | h | a | r | v | e | y | 属性长度(3) | 35(Topic Alias) | 00000000 | 00000001 |
注意:
“主题长度” 在MQTT规范中没有直接说明,参见“3.3.2.1 Topic Name”,能知晓长度占两个字节约束可参见"Figure 3-9 - PUBLISH packet Variable Header non-normative example"
payload(8个字节)
| 01010011 | 01101000 | 01100001 | 01101110 | 01100111 | 01001000 | 01100001 | 01101001 |
|---|
| S | h | a | n | g | H | a | i |
QoS-1
实验日志
2023-08-31 08:51:46:860 Send 包类型:PUBLISH
2023-08-31 08:51:46:860 Send Message Header(二进制内容) : 00110010 00010110 00000000 00000110 01101000 01100001 01110010 01110110 01100101 01111001 00000000 00000001 00000011 00100011 00000000 00000001
2023-08-31 08:51:46:860 Send Message Header(字符串内容) : 2harvey#
2023-08-31 08:51:46:860 Send Message payload(二进制内容) : 01010011 01101000 01100001 01101110 01100111 01001000 01100001 01101001
2023-08-31 08:51:46:861 Send Message payload(字符串内容) : 内容长度=8,内容=ShangHai
2023-08-31 08:51:46:861 Receive 包类型:PUBACK
2023-08-31 08:51:46:861 Receive Message Header(二进制内容) : 01000000 00000010 00000000 00000001
2023-08-31 08:51:46:861 Receive Message Header(字符串内容) : @
2023-08-31 08:51:46:861 Receive Message payload(二进制内容) :
2023-08-31 08:51:46:861 Receive Message payload(字符串内容) :
PUBLISH协议
固定头
| 包类型 | 剩余长度 |
|---|
| 00110010 | 00010110 |
| 参见“3.3.1 PUBLISH Fixed Header” | 22个字节 |
可变头(14个字节)
Topic Name + Packet Identifier + Properties
| 00000000 | 00000110 | 01101000 | 01100001 | 01110010 | 01110110 | 01100101 | 01111001 | 00000000 | 00000001 | 00000011 | 00100011 | 00000000 | 00000001 |
|---|
| 主题 | 长度(6) | h | a | r | v | e | y | Packet | Identifier | 属性长度(3) | 35(Topic Alias) | 00000000 | 00000001 |
payload(8个字节)
| 01010011 | 01101000 | 01100001 | 01101110 | 01100111 | 01001000 | 01100001 | 01101001 |
|---|
| S | h | a | n | g | H | a | i |
PUBACK协议
固定头
| 包类型 | 剩余长度 |
|---|
| 01000000 | 00000010 |
| 参见“3.4.1 PUBACK Fixed Header” | 2个字节 |
可变头(2个字节)
| 00000000 | 00000001 |
|---|
| Packet Identifier MSB | Packet Identifier LSB |
格式详情参见 “3.4.2 PUBACK Variable Header”
QoS-2
实验日志
2023-08-31 08:52:08:878 Send 包类型:PUBLISH
2023-08-31 08:52:08:878 Send Message Header(二进制内容) : 00110100 00010110 00000000 00000110 01101000 01100001 01110010 01110110 01100101 01111001 00000000 00000001 00000011 00100011 00000000 00000001
2023-08-31 08:52:08:878 Send Message Header(字符串内容) : 4�harvey�#�
2023-08-31 08:52:08:879 Send Message payload(二进制内容) : 01010011 01101000 01100001 01101110 01100111 01001000 01100001 01101001
2023-08-31 08:52:08:879 Send Message payload(字符串内容) : 内容长度=8,内容=ShangHai
2023-08-31 08:52:08:879 Receive 包类型:PUBREC
2023-08-31 08:52:08:880 Receive Message Header(二进制内容) : 01010000 00000010 00000000 00000001
2023-08-31 08:52:08:880 Receive Message Header(字符串内容) : P�
2023-08-31 08:52:08:881 Receive Message payload(二进制内容) :
2023-08-31 08:52:08:881 Receive Message payload(字符串内容) :
2023-08-31 08:52:08:882 Send 包类型:PUBREL
2023-08-31 08:52:08:882 Send Message Header(二进制内容) : 01100010 00000010 00000000 00000001
2023-08-31 08:52:08:882 Send Message Header(字符串内容) : b�
2023-08-31 08:52:08:883 Send Message payload(二进制内容) :
2023-08-31 08:52:08:883 Send Message payload(字符串内容) : 内容长度=0,内容=
2023-08-31 08:52:08:883 Receive 包类型:PUBCOMP
2023-08-31 08:52:08:884 Receive Message Header(二进制内容) : 01110000 00000010 00000000 00000001
2023-08-31 08:52:08:884 Receive Message Header(字符串内容) : p�
2023-08-31 08:52:08:884 Receive Message payload(二进制内容) :
2023-08-31 08:52:08:884 Receive Message payload(字符串内容) :
PUBLISH协议
固定头
| 包类型 | 剩余长度 |
|---|
| 00110100 | 00010110 |
| 参见“3.3.1 PUBLISH Fixed Header” | 22个字节 |
可变头(14个字节)
Topic Name + Packet Identifier + Properties
| 00000000 | 00000110 | 01101000 | 01100001 | 01110010 | 01110110 | 01100101 | 01111001 | 00000000 | 00000001 | 00000011 | 00100011 | 00000000 | 00000001 |
|---|
| 主题 | 长度(6) | h | a | r | v | e | y | Packet | Identifier | 属性长度(3) | 35(Topic Alias) | 00000000 | 00000001 |
payload(8个字节)
| 01010011 | 01101000 | 01100001 | 01101110 | 01100111 | 01001000 | 01100001 | 01101001 |
|---|
| S | h | a | n | g | H | a | i |
PUBREC协议
固定头
| 包类型 | 剩余长度 |
|---|
| 01010000 | 00000010 |
| 参见“3.5.1 PUBREC Fixed Header” | 2个字节 |
可变头(2个字节)
| 00000000 | 00000001 |
|---|
| Packet Identifier MSB | Packet Identifier LSB |
格式详情参见 “3.5.2 PUBREC Variable Header”
PUBREL协议
固定头
| 包类型 | 剩余长度 |
|---|
| 01100010 | 00000010 |
| 参见“3.6.1 PUBREL Fixed Header” | 2个字节 |
可变头(2个字节)
| 00000000 | 00000001 |
|---|
| Packet Identifier MSB | Packet Identifier LSB |
格式详情参见 “3.6.2 PUBREL Variable Header”
PUBCOMP协议
固定头
| 包类型 | 剩余长度 |
|---|
| 01110000 | 00000010 |
| 参见“3.7.1 PUBCOMP Fixed Header” | 2个字节 |
可变头(2个字节)
| 00000000 | 00000001 |
|---|
| Packet Identifier MSB | Packet Identifier LSB |
格式详情参见 “3.7.2 PUBCOMP Variable Header”