MQTT 协议交互流程
1. 连接建立流程
sequenceDiagram
participant C as Client
participant B as Broker
C->>B: CONNECT
(clientId, username, password,
will, cleanSession) B-->>C: CONNACK
(returnCode: 0=成功) Note over C,B: 连接建立完成
(clientId, username, password,
will, cleanSession) B-->>C: CONNACK
(returnCode: 0=成功) Note over C,B: 连接建立完成
# CONNECT 报文示例
Packet Type: 0001 (CONNECT)
Flags: 0000
Remaining Length: variable
Payload:
- Protocol Name: "MQTT"
- Protocol Level: 4 (MQTT 3.1.1) or 5 (MQTT 5.0)
- Connect Flags:
* Clean Session: 1
* Will Flag: 0
* Will QoS: 00
* Will Retain: 0
* Password Flag: 1
* Username Flag: 1
- Keep Alive: 60 秒
- Client ID: "my-client-001"
- Username: "user123"
- Password: "pass456"
2. QoS 0 发布流程
sequenceDiagram
participant Pub as Publisher
participant B as Broker
participant Sub as Subscriber
Pub->>B: PUBLISH (QoS 0)
topic: "sensors/temp"
payload: "25.5°C" B->>Sub: PUBLISH (QoS 0)
topic: "sensors/temp" Note over Pub,Sub: 无确认,消息可能丢失
topic: "sensors/temp"
payload: "25.5°C" B->>Sub: PUBLISH (QoS 0)
topic: "sensors/temp" Note over Pub,Sub: 无确认,消息可能丢失
📌 QoS 0 特点
- 最多一次:消息最多传递一次,不保证送达
- 无确认机制:发送后不等待任何响应
- 最低开销:只有一个 PUBLISH 报文
- 适用场景:传感器数据频繁上报,允许少量丢失
3. 发布/订阅流程(QoS 1)
sequenceDiagram
participant Pub as Publisher
participant B as Broker
participant Sub as Subscriber
Sub->>B: SUBSCRIBE
(topic: "sensors/temp", QoS: 1) B-->>Sub: SUBACK
(Message ID: 1, Return QoS: 1) Note over Pub,Sub: 订阅完成,开始发布消息 Pub->>B: PUBLISH
(topic: "sensors/temp"
payload: "25.5°C") B-->>Pub: PUBACK
(Message ID: 100) B->>Sub: PUBLISH
(delivered to subscriber) Sub-->>B: PUBACK
(acknowledge)
(topic: "sensors/temp", QoS: 1) B-->>Sub: SUBACK
(Message ID: 1, Return QoS: 1) Note over Pub,Sub: 订阅完成,开始发布消息 Pub->>B: PUBLISH
(topic: "sensors/temp"
payload: "25.5°C") B-->>Pub: PUBACK
(Message ID: 100) B->>Sub: PUBLISH
(delivered to subscriber) Sub-->>B: PUBACK
(acknowledge)
4. QoS 2 完整握手流程
sequenceDiagram
participant Pub as Publisher
participant B as Broker
participant Sub as Subscriber
Pub->>B: PUBLISH (QoS 2)
Message ID: 123 B-->>Pub: PUBREC
Message ID: 123 Pub->>B: PUBREL
Message ID: 123 B-->>Pub: PUBCOMP
Message ID: 123 Note over B,Sub: Broker 将消息分发给订阅者 B->>Sub: PUBLISH (QoS 2) Sub-->>B: PUBREC B->>Sub: PUBREL Sub-->>B: PUBCOMP
Message ID: 123 B-->>Pub: PUBREC
Message ID: 123 Pub->>B: PUBREL
Message ID: 123 B-->>Pub: PUBCOMP
Message ID: 123 Note over B,Sub: Broker 将消息分发给订阅者 B->>Sub: PUBLISH (QoS 2) Sub-->>B: PUBREC B->>Sub: PUBREL Sub-->>B: PUBCOMP
📌 QoS 2 四次握手说明
- PUBLISH: 发布者发送消息
- PUBREC: Broker 确认收到(Publish Received)
- PUBREL: 发布者释放消息(Publish Release)
- PUBCOMP: Broker 确认完成(Publish Complete)
通过 4 次握手保证消息"恰好送达一次",既不丢,也不重复
5. 遗嘱消息(Last Will)
sequenceDiagram
participant C as Client
participant B as Broker
participant S as Subscribers
C->>B: CONNECT
Will Topic: "device/status"
Will Payload: "offline"
Will Retain: true B-->>C: CONNACK
连接成功 Note over C,B: 客户端正常在线 C--xB: ⚠️ 异常断开 Note over B: 检测到连接丢失 B->>S: PUBLISH (Will)
topic: "device/status"
payload: "offline"
(Retained)
Will Topic: "device/status"
Will Payload: "offline"
Will Retain: true B-->>C: CONNACK
连接成功 Note over C,B: 客户端正常在线 C--xB: ⚠️ 异常断开 Note over B: 检测到连接丢失 B->>S: PUBLISH (Will)
topic: "device/status"
payload: "offline"
(Retained)
6. 心跳保活机制
sequenceDiagram
participant C as Client
participant B as Broker
C->>B: CONNECT
Keep Alive: 60s B-->>C: CONNACK loop 每 < 60 秒 C->>B: PINGREQ B-->>C: PINGRESP end Note over C,B: 如果 1.5 倍 Keep Alive 时间
内无消息,Broker 断开连接
Keep Alive: 60s B-->>C: CONNACK loop 每 < 60 秒 C->>B: PINGREQ B-->>C: PINGRESP end Note over C,B: 如果 1.5 倍 Keep Alive 时间
内无消息,Broker 断开连接
⚠️ 保活超时
如果 Broker 在 1.5 倍 Keep Alive 时间内未收到任何消息,将断开连接并触发遗嘱消息(如果已设置)。
7. 断开连接
sequenceDiagram
participant C as Client
participant B as Broker
C->>B: DISCONNECT
优雅断开 B-->>C: 连接关闭 Note over B: 不触发遗嘱消息
优雅断开 B-->>C: 连接关闭 Note over B: 不触发遗嘱消息
8. 完整会话流程
sequenceDiagram
participant Pub as Publisher
participant B as Broker
participant Sub as Subscriber
Pub->>B: CONNECT
B-->>Pub: CONNACK
Sub->>B: CONNECT
B-->>Sub: CONNACK
Sub->>B: SUBSCRIBE
(topic: "home/#") B-->>Sub: SUBACK loop 消息发布 Pub->>B: PUBLISH
(topic: "home/temp") B-->>Pub: PUBACK B->>Sub: PUBLISH Sub-->>B: PUBACK end Pub->>B: DISCONNECT Sub->>B: DISCONNECT
(topic: "home/#") B-->>Sub: SUBACK loop 消息发布 Pub->>B: PUBLISH
(topic: "home/temp") B-->>Pub: PUBACK B->>Sub: PUBLISH Sub-->>B: PUBACK end Pub->>B: DISCONNECT Sub->>B: DISCONNECT