Publishing process of MQTT protocol

1 PUBLISH

The message published by the client is distributed to all corresponding subscribers via the server. A subscriber can subscribe to several topics (Topic name), but a PUBLISH message can only have one topic.

Overview of message architecture:

Description 7 6 5 4 3 2 1 0
Fixed header/Fixed header
byte 1 Message Type(3) DUP flag QoS level RETAIN
0 0 1 1 0 0 1 0
byte 2 Remaining Length
Variable header / variable header
Topic name
byte 1 Length MSB (0) 0 0 0 0 0 0 0 0
byte 2 Length LSB (3) 0 0 0 0 0 0 1 1
byte 3 'a' (0x61) 0 1 1 0 0 0 0 1
byte 4 '/' (0x2F) 0 0 1 0 1 1 1 1
byte 5 'b' (0x62) 0 1 1 0 0 0 1 0
Message Identifier
byte 6 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 7 Message ID LSB (10) 0 0 0 0 1 0 1 0
Playload/message body
BLOB, binary object form. The specific content and format contained in the binary can be defined by the application itself. It is also possible if the message body is empty (0 length).

2 fixed head

DUP flag, set to 0, means that it is the first sending.

RETAIN flag is valid only in PUBLISH messages.

  • 1: Indicates that the sent message needs to be kept persistently, not only to the current subscriber, but also to the new subscriber who subscribes to this Topic name in the future and will be pushed immediately. Remarks: New subscribers will only fetch the latest message push with RETAIN flag = 1, not all of them.
  • 0: Only push this message for the current subscriber.

3 variable heads

Topic name, UTF-8 encoded string form, does not support wildcards!

4 message body

Generally written to the interface as UTF-8 encoding, but custom message formats are not excluded.

PUBLISH messages with empty message bodies (zero-length) are also legal.

When the server receives a PUBLISH special message with an empty message body (zero-length payload), retain = 1, and topic name, it means that the persistent PUBLISH message that satisfies the two characteristics of retain = 1 and the same topic name can be been deleted.

5 Response/response

The fixed header QoS level determines what the message middleware needs to respond to the publisher:

QoS Level Expected response
QoS 0 None
QoS 1 PUBACK
QoS 2 PUBREC

Remarks: Only for publishers who publish PUBLISH messages.

6 Actions:

Both the subscriber and the server need to perform different actions according to the QoS level after receiving the PUBLISH message.

QoS Level Expected Action
QoS 0 send to all interested
QoS 1 Persistently record it, send it to all interested participants, and return a PUBACK message to the sender
QoS 2 Make a persistent record, temporarily not send all interested participants, and return a PUBREC message to the sender

A participant refers to a subscriber if the server receives a PUBLISH message. If a subscriber receives a PUBLISH message, the participant is the server. requires attention:

  1. The PUBLISH message issued by the publisher is sent to the server, and there may be private goods in the payload/message body, which may contain a custom data format
  2. If it is compatible with the MQTT client, it can only be a regular PUBLISH message distributed to all corresponding subscribers via the server, and the RETAIN flag of the fixed header cannot be set to a valid value of 1

7 authorization

The PUBLISH message submitted by an unauthorized publisher will be ignored by the server, and the client will not be notified.

8 PUBACK

As a response to the sender after the subscriber/server receives (QoS level = 1) PUBLISH message, the whole message is not complicated.

Description 7 6 5 4 3 2 1 0
Fixed header/Fixed header
byte 1 Message type (4) DUP flag QoS flags RETAIN
0 1 0 0 x x x x
byte 2 Remaining Length (2)
0 0 0 0 0 0 1 0
Variable header / variable header
Message Identifier
byte 1 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 2 Message ID LSB (10) 0 0 0 0 1 0 1 0

虽没有消息体,但可变头部附加一个16位的无符号short类型。

9 PUBREC

字面意思为Assured publish received,作为订阅者/服务器对QoS level = 2的发布PUBLISH消息的发送方的响应,确认已经收到,为QoS level = 2消息流的第二个消息。 和PUBACK相比,除了消息类型不同外,其它都是一样。

Description 7 6 5 4 3 2 1 0
Fixed header/固定头部
byte 1 Message type (5) DUP flag QoS flags RETAIN
0 1 0 1 x x x x
byte 2 Remaining Length (2)
0 0 0 0 0 0 1 0
Variable header/可变头部
Message Identifier
byte 1 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 2 Message ID LSB (10) 0 0 0 0 1 0 1 0

无论是订阅者还是服务器,在消费PUBREC消息之后需要发送一个PUBREL消息给发送者(和PUBREC具有同样的消息ID),确认已收到。

10 PUBREL

Qos level = 2的协议流的第三个消息,有PUBLISH消息的发布者发送,参与方接收。完整示范如下:

Description 7 6 5 4 3 2 1 0
Fixed header/固定头部
byte 1 Message type (6) DUP flag QoS flags RETAIN
0 1 1 0 0 0 1 x
byte 2 Remaining Length (2)
0 0 0 0 0 0 1 0
Variable header/可变头部
Message Identifier
byte 1 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 2 Message ID LSB (10) 0 0 0 0 1 0 1 0

QoS level 1,PUBREL消息要求如此。

DUP flag 为0,表示消息第一次被发送。

毫无疑问,剩余长度为2个byte长度。

可变头部中,消息ID和发布者接收到的PUBREC所包含的消息ID是一致的。

动作:

  1. 服务器接收到发布者(a)的PUBREL消息,此时服务器让发布者(a)刚才发布PUBLISH消息可用,发送此PUBLISH消息给所有订阅此主题的订阅者,然后发送PUBCOMP消息给发布者(a)
  2. 可变头部包含消息ID和服务器接收的PUBREL消息ID是一致的。 一个订阅者接收到PUBREL消息,订阅者使PUBLISH消息可用,然后反馈一个PUBCOMP消息给服务器

11 PUBCOMP

作为QoS level = 2消息流第四个,也是最后一个消息,由收到PUBREL的一方向另一方做出的响应消息。

完整的消息一览,和PUBREL一致,除了消息类型。

Description 7 6 5 4 3 2 1 0
Fixed header/固定头部
byte 1 Message type (7) DUP flag QoS flags RETAIN
0 1 1 1 x x x x
byte 2 Remaining Length (2)
0 0 0 0 0 0 1 0
Variable header/可变头部
Message Identifier
byte 1 Message ID MSB (0) 0 0 0 0 0 0 0 0
byte 2 Message ID LSB (10) 0 0 0 0 1 0 1 0

当客户端接收一个PUBCOMP消息时,客户端摒弃原来的消息,因为它已经成功发送消息到服务器。

小结

消息的发布和确认等一些流程,主要是跟消息发布者所设定的QoS level有关;稍加整理,如下图所示:

Publish流程图

上图针对的是客户端发布消息到服务器端的方向。

为了确保消息已经成功传递过去,只有收到了确认,才会让人特别放心。

在QoS level = 2时,通信双方都需要知道各自的确认流程以及所处阶段等,交互很多,数据量大的情况下,可能会造成数据线路传递拥塞。服务器选择QoS = 0/1,大部分情况都是可以应对的。 比如重要消息,就要确保对方都要收到,然后彼此确认,OK,这个消息是真实、有效的。

无论Qos level为0、1,还是2,服务器(具备所有条件都满足之后)总要把收到的具体内容和topic组装成一个新的PUBLISH Message(也不一定要重新构造,但要求推送的PUBLISH消息,一定要具有明确的主题和内容,RETAIN标志不能设置为1)推送到所有感兴趣的订阅者。

嗯,消息的发布来源别忘记还有可能来自CONNECT消息中的Will Topic和Will Message,若是设置了Will flag标记的话。

 

Guess you like

Origin blog.csdn.net/lsb2002/article/details/103629167