發佈與訂閱流程
- ClientA 連接到 Broker;
- ClientB 連接到 Broker,並訂閱主題 Topic1;
- ClientA 發送給 Broker 一條消息,主題爲 Topic1;
- Broker 收到 ClientA 的消息,發現 ClientB 訂閱了 Topic1,然後將消息轉發到 ClientB;
- ClientB 從 Broker 接收到該消息。
消息離線接收
接收離線的消息需要 Client 使用持久化會話,且發佈時消息的 QoS 不小於 1。
Publisher 和 Subscriber
Publisher 和 Subscriber 是相對於 Topic 來說的身份,如果一個 Client 向某個 Topic 發佈消息,那麼它就是 Publisher;如果一個 Client 訂閱了某個 Topic,那麼它就是 Subscriber。
Sender 和 Receiver
Sender 和 Receiver 是相對於消息傳輸方向的身份,例子:
- 當 ClientA 發佈消息時,它發送給 Broker 一條消息,那麼 ClientA 是 Sender,Broker 是 Receiver;
- 當 Broker 轉發消息給 ClientB 時,Broker 是 Sender,ClientB 是 Receiver。
PUBLISH
PUBLISH 數據包是用於在 Sender 和 Receiver 之間傳輸消息數據的,也就是說,當 Publisher 要向某個 Topic 發佈一條消息的時候,Publisher 會向 Broker 發送一個 PUBLISH 數據包;當 Broker 要將一條消息轉發給訂閱了某條主題的 Subscriber 時,Broker 也會向 Subscriber 發送一條 PUBLISH 數據包。
固定頭
- 消息重複標識(DUP flag):1bit,0 或者 1,當 DUP flag = 1 的時候,代表該消息是一條重發消息,因 Receiver 沒有確認收到之前的消息而重新發送的。這個標識只在 QoS 大於 0 的消息中使用。
- QoS:2bit,0、1 或者 2,代表 PUBLISH 消息的 QoS level。
- Retain 標識(Retain flag):1bit,0 或者 1,在從 Client 發送到 Broker 的 PUBLISH 消息中被設爲 1 的時候,Broker 應該保存該條消息,當之後有任何新的 Subscriber 訂閱 PUBLISH 消息中指定的主題時,都會先收到該條消息,這種消息也叫 Retained 消息;在從 Broker 發送到 Client 的 PUBLISH 消息中被設爲 1 的時候,代表該條消息是一條 Retained 消息。
可變頭
- 數據包標識( Packet Identifier):2bit,用來標識一個唯一數據包,數據包標識只需要保證在從 Sender 到 Receiver 的一次消息交互(比如發送、應答爲一次交互)中保持唯一。只在 QoS 不小於 1 的消息中使用,因爲只有 QoS 不小於 1 的消息有應答流程。
- 主題名稱(Topic Name):主題名稱是一個 UTF-8 編碼的字符串,用來命名該消息發佈到哪一個主題,Topic Name 可以是長度大於等於 1 任何一個字符串(可包含空格),但是在實際項目中,我們最好還是遵循以下一些最優方法。
- 主題名稱應該包含層級,不同的層級用 / 劃分,比如,2 樓 201 房間的溫度感應器可以用這個主題:“home/2ndfloor/201/temperature”。
- 主題名稱開頭不要使用 /,例如:“/home/2ndfloor/201/temperature”。
- 不要在主題中使用空格。
- 只使用 ASCII 字符。
- 主題名稱在可讀的前提下儘量短。
- 主題是大小寫敏感的,“Home” 和 “home” 是兩個不同的主題。
- 可以將設備的唯一標識加到主題中,比如:“warehouse/shelf/shelf1_ID/status”。
- 主題儘量精確,不要使用泛用的主題,例如在 201 房間有三個傳感器,溫度、亮度和溼度,那麼你應該使用三個主題名稱:“home/2ndfloor/201/temperature”、“home/2ndfloor/201/brightness”和“home/2ndfloor/201/humidity”,而不是讓三個傳感器都使用“home/2ndfloor/201”。
- 以 $ 開頭的主題屬於 Broker 預留的系統主題,通常用於發佈 Broker 的內部統計信息,比如 $SYS/broker/clients/connected,應用程序不要使用 $ 開頭的主題收發數據。
消息體
PUBLISH 消息的消息體中包含的是該消息要發送的具體數據,數據可以是任何格式的,二進制數據、文本、JSON 。
訂閱
- Client 向 Broker 發送一個 SUBSCRIBE 數據包,其中包含了 Client 想要訂閱的主題以及其他一些參數;
- Broker 收到 SUBSCRIBE 數據包後,向 Client 發送一個 SUBACK 數據包作爲應答。
SUBSCRIBE
可變頭
- 數據包標識(Packet Identifier):兩個字節,用來唯一標識一個數據包,數據包標識只需要保證在從 Sender 到 Receiver 的一次消息交互中保持唯一。
消息體
- 訂閱列表(List of Subscriptions):SUBSCRIBE 的消息體中包含 Client 想要訂閱的主題列表,列表中的每一項由訂閱主題名和對應的 QoS 組成。
SUBACK
可變頭
- 數據包標識(Packet Identifier):兩個字節,用來唯一標識一個數據包,數據包標識只需要保證在從 Sender 到 Receiver 的一次消息交互中保持唯一。
消息體
- 返回碼:
返回碼 | 含義 |
---|---|
0 | 訂閱成功, 最大可用QoS爲0 |
1 | 訂閱成功,最大可用QoS爲1 |
2 | 訂閱成功, 最大可用QoS爲2 |
128 | 訂閱失敗 |