MQTT-Java PUBLISH系列协议

128 阅读10分钟

目标

理解客户端在不同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协议

固定头

包类型剩余长度
0011000000010100
参见“3.3.1 PUBLISH Fixed Header”20个字节

可变头(12个字节)

Topic Name + Packet Identifier + Properties

000000000000011001101000011000010111001001110110011001010111100100000011001000110000000000000001
主题长度(6)harvey属性长度(3)35(Topic Alias)0000000000000001

注意:
“主题长度” 在MQTT规范中没有直接说明,参见“3.3.2.1 Topic Name”,能知晓长度占两个字节约束可参见"Figure 3-9 - PUBLISH packet Variable Header non-normative example"

payload(8个字节)

0101001101101000011000010110111001100111010010000110000101101001
ShangHai

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协议

固定头

包类型剩余长度
0011001000010110
参见“3.3.1 PUBLISH Fixed Header”22个字节

可变头(14个字节)

Topic Name + Packet Identifier + Properties

0000000000000110011010000110000101110010011101100110010101111001000000000000000100000011001000110000000000000001
主题长度(6)harveyPacketIdentifier属性长度(3)35(Topic Alias)0000000000000001

payload(8个字节)

0101001101101000011000010110111001100111010010000110000101101001
ShangHai

PUBACK协议

固定头

包类型剩余长度
0100000000000010
参见“3.4.1 PUBACK Fixed Header”2个字节

可变头(2个字节)

0000000000000001
Packet Identifier MSBPacket 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协议

固定头

包类型剩余长度
0011010000010110
参见“3.3.1 PUBLISH Fixed Header”22个字节

可变头(14个字节)

Topic Name + Packet Identifier + Properties

0000000000000110011010000110000101110010011101100110010101111001000000000000000100000011001000110000000000000001
主题长度(6)harveyPacketIdentifier属性长度(3)35(Topic Alias)0000000000000001

payload(8个字节)

0101001101101000011000010110111001100111010010000110000101101001
ShangHai

PUBREC协议

固定头

包类型剩余长度
0101000000000010
参见“3.5.1 PUBREC Fixed Header”2个字节

可变头(2个字节)

0000000000000001
Packet Identifier MSBPacket Identifier LSB

格式详情参见 “3.5.2 PUBREC Variable Header”

PUBREL协议

固定头

包类型剩余长度
0110001000000010
参见“3.6.1 PUBREL Fixed Header”2个字节

可变头(2个字节)

0000000000000001
Packet Identifier MSBPacket Identifier LSB

格式详情参见 “3.6.2 PUBREL Variable Header”

PUBCOMP协议

固定头

包类型剩余长度
0111000000000010
参见“3.7.1 PUBCOMP Fixed Header”2个字节

可变头(2个字节)

0000000000000001
Packet Identifier MSBPacket Identifier LSB

格式详情参见 “3.7.2 PUBCOMP Variable Header”