PUBLISH报文及其响应

PUBLISH控制报文是指从Client端向Broker端或者Broker端向Client端传输一个应用消息,用于消息的发布。

Publish Over SSH Remote Directory如何获取_重发

PUBLISH报文头的第一个字节中,bit2和bit1用于设置QoS级别,可设置为0,1,2。MQTT协议规定,PUBLISH报文根据不同的QoS级别,其报文响应机制不同,如下图所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ezyAj0L9-1590393201757)(C:\Users\ThinkPad\AppData\Roaming\Typora\typora-user-images\image-20200521101412930.png)]

固定报头

如下表格描述了PUBLISH报文固定报头格式。

字段

描述

byte1

bit7-bit4:MQTT控制报文类型 bit3: DUP bit2-bit1:QoS级别 bit0:RETAIN

byte2…

剩余长度

重发标志DUP

如果DUP被设置为0,表示这是Clinet端或者Broker端第一次请求发送这个报文。如果DUP被设置为1,表示这可能是一个报文请求的重发。

Client端或Broker端请求重发一个PUBLISH报文时,必须将DUP标志设置为1.对于QoS为0的报文,DUP标志必须设置为0.

Broker端发送PUBLISH报文给订阅者时,收到的PUBLISH报文的DUP标志的值不会被传播。Client发送的PUBLISH和收到的PUBLISH中的DUP标志是独立设置的,没有互相关系,其值必须单独的根据发送的PUBLISH报文是否是一个重发来确定。

QoS服务质量等级

QoS字段表示应用消息分发的服务质量等级。如下表格所示

QoS

bit2

bit1

描述

0

0

0

最多分发一次

1

0

1

至少分发一次

2

1

0

只分发一次

-

1

1

保留

PUBLISH报文不能将QoS所有的位都设为1。如果收到的QoS所有位都为1,必须关闭网络连接。

RETAIN保留保留标志位

如果Client端发送给Broker端的PUBLISH报文的RETAIN位被设置为1,Broker端必须存储这个应用消息和它的QoS,以便可以分发给未来的主题名匹配的订阅者。一个新的订阅创建时,对每个匹配的主题名,如果存在最近保留的消息,它必须被发送给订阅者。如果Broker端收到一条保留标志为1的QoS0消息,它必须丢弃之前为那个主题保留的任何消息,并且应该将这个新的QoS0消息当做那个主题的新的保留消息,但是任何时候都可以选择丢弃它,如果这种情况发生了,那么该主题将没有保留消息。

Broker端发送PUBLISH报文给Clinet端时,如果消息是作为Client端一个新订阅的结果发送,必须将报文的保留标志位设为1。当一个PUBLISH报文发送给Client端是因为匹配一个已建立的订阅时,Broker端必须将保留标志位设为0,不管它收到的这个消息中保留标志的值是多少。

保留标志位为1,有效载荷为零字节的PUBLISH报文会被Broker端当作正常消息处理,它会被发送给订阅主题匹配的Client端。此外,同一个主题下任何现存的保留信息必须被移除,因此这个主题之后的任何订阅者都不会受到一个保留信息。
保留标志为1且有效载荷为零字节的PUBLISH报文会被Broker端“当作正常”消息处理,它会被发送给订阅主题匹配的Client端。此外,同一个主题下任何现存的保留消息必须被移除,因此这个主题之后的任何订阅者都不会收到一个保留消息 。“当作正常”意思是现存的Client端收到的消息中保留标志未被设置。Broker端不能存储零字节的保留消息 。如果Client端发给Broker端的PUBLISH报文的保留标志位0,Broker端不能存储这个消息也不能移除或替换任何现存的保留消息 。

如果Client端发给Broker端的PUBLISH报文的保留标志位0,Broker端不能存储这个消息也不能移除或替换任何现存的保留消息。

剩余长度

等于可变报头的长度加上有效载荷的长度。

可变报头

可变报头组成如下表所示:

字段

描述

Topic Name主题名

例如:a,b, temperature

Packet Identifier报文标识符

10

主题名

主题名(Topic Name)用于识别有效载荷数据应该被发布到哪一个信息通道。
主题名必须是PUBLISH报文可变报头的第一个字段,必须是 UTF-8编码的字符串,且不能 包含通配符。
Broker端发送给订阅Client端的PUBLISH报文的主题名必须匹配该订阅的主题过滤器。

报文标识符

只有当QoS等级是1或2时,报文标识符(Packet Identifier)字段才能出现在PUBLISH报文中,可以参考《MQTT报文分析》。

有效载荷

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

动作 Actions

Client端使用PUBLISH报文发送应用消息给Broker端,目的是分发到其它订阅匹配的Client端。
Broker端使用PUBLISH报文发送应用消息给每一个订阅匹配的Client端。

Client端使用带通配符的主题过滤器请求订阅时,Client端的订阅可能会重复,因此发布的消息可能会匹配多个过滤器。对于这种情况,Broker端必须将消息分发给所有订阅匹配的QoS等级最高的Client端 。Broker端之后可以按照订阅的QoS等级,分发消息的副本给每一个匹配的订阅者。

收到一个PUBLISH报文时,接收者的动作取决于QoS等级。如果Broker端实现不授权某个Client端发布PUBLISH报文,它没有办法通知那个Client端。它必须按照正常的QoS规则发送一个正面的确认,或者关闭网络连接。

PUBACK-发布确认

PUBACK报文是对QoS 1等级的PUBLISH报文的响应,其组成如下图所示

字段

描述

固定报头

2字节

可变报头

2字节

固定报头

固定报头如下表所示

字段

描述

byte1

bit7-bit4:MQTT报文类型 bit3-bit0:保留位

byte2

剩余长度:PUBACK报文头这个值为0x02

可变报头

可变报头如下表所示

字段

描述

byte1

报文标识符MSB

byte2

报文标识符LSB

动作

参考后续文章,MQTT协议的操作行为

PUBREC – 发布收到(QoS 2,第一步)

PUBREC报文是对QoS等级2的PUBLISH报文的响应,它是QoS 2等级协议交换的第二个报文,其组成如下表所示:

字段

描述

固定报头

2字节

可变报头

2字节

固定报头

固定报头如下表所示

字段

描述

byte1

bit7-bit4:MQTT报文类型 bit3-bit0:保留位

byte2

剩余长度:PUBREC报文头这个值为0x02

可变报头

可变报头如下表所示

字段

描述

byte1

报文标识符MSB

byte2

报文标识符LSB

动作

参考后续文章,MQTT协议的操作行为

PUBREL – 发布释放(QoS 2,第二步)

PUBREL报文是对PUBREC报文的响应。它是QoS 2等级协议交换的第三个报文,其组成如下所示:

字段

描述

固定报头

2字节

可变报头

2字节

固定报头

固定报头如下表所示:

字段

描述

byte1

bit7-bit4:MQTT报文类型 bit3-bit0:保留位,必须设置为0010

byte2

剩余长度:PUBREL报文头这个值为0x02

可变报头

可变报头如下表所示

字段

描述

byte1

报文标识符MSB

byte2

报文标识符LSB

动作

参考后续文章,MQTT协议的操作行为

PUBCOMP – 发布完成(QoS 2,第三步)

PUBCOMP报文是对PUBREL报文的响应。它是QoS 2等级协议交换的第四个也是最后一个报文,其组成如下表所示:

字段

描述

固定报头

2字节

可变报头

2字节

固定报头

固定报头如下表所示

字段

描述

byte1

bit7-bit4:MQTT报文类型 bit3-bit0:保留位

byte2

剩余长度:PUBCOMP报文头这个值为0x02

可变报头

可变报头如下表所示

字段

描述

byte1

报文标识符MSB

byte2

报文标识符LSB

动作

参考后续文章,MQTT协议的操作行为

引用

1 《MQTT协议中文版本》:https://mcxiaoke.gitbooks.io/mqtt-cn/content/

可变报头如下表所示

字段

描述

byte1

报文标识符MSB

byte2

报文标识符LSB

动作

参考后续文章,MQTT协议的操作行为

引用

1 《MQTT协议中文版本》:https://mcxiaoke.gitbooks.io/mqtt-cn/content/

2 《MQTT Version 3.1.1》