3.8訂閱 - 訂閱主題
SUBSCRIBE數據包從客戶端發送到服務器以創建一個或多個訂閱。每個訂閱都註冊客戶對一個或多個主題的興趣。服務器將PUBLISH數據包發送到客戶端,以便將發佈的應用程序消息轉發到與這些訂閱匹配的主題。SUBSCRIBE數據包還指定(對於每個訂閱)服務器可以將應用程序消息發送到客戶端的最大QoS。
3.8.1 Fixed Header 固定標題
位 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
字節1 |
MQTT控制包類型(8) |
保留的 |
||||||
|
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
字節2 |
剩餘長度 |
SUBSCRIBE控制分組的固定報頭的比特3,2,1和0被保留,並且必須分別設置爲0,0,1和0。服務器必須將任何其他值視爲格式錯誤並關閉網絡連接 [MQTT-3.8.1-1] 。
剩餘長度字段
這是變量頭的長度(2個字節)加上有效載荷的長度。
3.8.2 varliable header 變量頭
變量頭包含數據包標識符。第2.3.1節提供了有關數據包標識符的更多信息。
圖3.21顯示了包標識符設置爲10的變量頭。
|
描述 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
包標識符 |
|||||||||
字節1 |
包標識符MSB(0) |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
字節2 |
包標識符LSB(10) |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
3.8.3 Payload 效載荷
SUBSCRIBE數據包的有效負載包含主題過濾器列表,指示客戶端要訂閱的主題。SUBSCRIBE數據包有效負載中的主題過濾器必須是第1.5.3 節[MQTT-3.8.3-1]中定義的UTF-8編碼字符串。服務器應該支持包含第4.7.1節中定義的通配符的主題過濾器。如果它選擇不支持包含通配符的主題過濾器,它必須拒絕其過濾器包含它們的任何訂閱請求 [MQTT-3.8.3-2]。每個過濾器後跟一個稱爲請求QoS的字節。這提供了服務器可以向客戶端發送應用程序消息的最大QoS級別。
SUBSCRIBE包的有效載荷必須包含至少一個主題過濾器/ QoS對。沒有有效載荷的SUBSCRIBE數據包是協議違規 [MQTT-3.8.3-3]。有關處理錯誤的信息,請參見第4.8節。
請求的最大QoS字段在每個UTF-8編碼的主題名稱後面的字節中編碼,並且這些主題過濾器/ QoS對被連續打包。
描述 |
7 |
6 |
五 |
4 |
3 |
2 |
1 |
0 |
主題過濾器 |
||||||||
字節1 |
長度MSB |
|||||||
字節2 |
長度LSB |
|||||||
字節3..N |
主題過濾器 |
|||||||
請求的QoS |
||||||||
|
保留的 |
服務質量 |
||||||
字節N + 1 |
0 |
0 |
0 |
0 |
0 |
0 |
X |
X |
請求的QoS字節的高6位不在當前版本的協議中使用。它們留作將來使用。如果有效載荷中的任何保留位非零,或者QoS不是0,1或2 [MQTT-3-8.3-4] ,則服務器必須將SUBSCRIBE數據包視爲格式錯誤並關閉網絡連接。
圖3.23 - 有效載荷字節格式非規範性示例顯示了表3.5中簡要描述的SUBSCRIBE數據包的有效載荷- 有效載荷非規範示例。
主題名稱 |
“A / B” |
請求的QoS |
0×01 |
主題名稱 |
“光盤” |
請求的QoS |
0×02 |
|
描述 |
7 |
6 |
五 |
4 |
3 |
2 |
1 |
0 |
主題過濾器 |
|||||||||
字節1 |
長度MSB(0) |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
字節2 |
長度LSB(3) |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
字節3 |
'a'(0x61) |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
字節4 |
'/'(0x2F) |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
字節5 |
'b'(0x62) |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
0 |
請求的QoS |
|||||||||
字節6 |
請求的QoS(1) |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
主題過濾器 |
|||||||||
字節7 |
長度MSB(0) |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
字節8 |
長度LSB(3) |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
字節9 |
'c'(0x63) |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
字節10 |
'/'(0x2F) |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
字節11 |
'd'(0x64) |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
請求的QoS |
|||||||||
字節12 |
請求的QoS(2) |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
3.8.4 Response 迴應
當服務器從客戶端收到SUBSCRIBE數據包時,服務器必須以SUBACK數據包 [MQTT-3.8.4-1]進行響應。SUBACK分組必須具有與其確認的SUBSCRIBE分組相同的分組標識符 [MQTT-3.8.4-2]。
在服務器發送SUBACK數據包之前,允許服務器開始發送與訂閱匹配的PUBLISH數據包。
如果服務器收到包含與現有Subscription主題過濾器相同的主題過濾器的SUBSCRIBE數據包,那麼它必須用新的訂閱完全替換現有的Subscription。新訂閱中的主題過濾器將與之前的訂閱中的主題過濾器相同,但其最大QoS值可能不同。必須重新發送與主題過濾器匹配的任何現有保留消息,但不得中斷出版物流 [ MQTT-3.8.4-3]。
如果主題過濾器與任何現有的Subscription過濾器不同,則會創建新的Subscription併發送所有匹配的保留消息。
如果服務器收到包含多個主題過濾器的SUBSCRIBE數據包,則它必須處理該數據包,就好像它已經收到多個SUBSCRIBE數據包的序列一樣,除了它將它們的響應組合成單個SUBACK響應 [MQTT-3.8.4-4]。
服務器發送給客戶端的SUBACK數據包必須包含每個主題過濾器/ QoS對的返回碼。此返回代碼必須顯示爲該訂閱授予的最大QoS或指示訂閱失敗[ MQTT- 3.8.4-5] 。服務器可能授予比請求的訂戶更低的最大QoS。響應訂閱而發送的有效載荷消息的QoS必須是最初發布的消息的QoS的最小值和服務器授予的最大QoS。在原始消息以QoS 1發佈並且授予的最大QoS爲QoS 0 [ MQTT-3 .8.4-6] 的情況下,允許服務器向訂戶發送消息的重複副本。
非規範性示例
如果訂閱客戶端已被授予特定主題過濾器的最大QoS 1,則匹配過濾器的QoS 0應用程序消息將以QoS 0傳送到客戶端。這意味着最多隻有一個副本的消息被接收客戶端。另一方面,發佈到同一主題的QoS 2消息被服務器降級爲QoS 1以傳遞到客戶端,因此客戶端可能會收到消息的重複副本。
如果訂閱客戶端已被授予最大QoS 0,則最初作爲QoS 2發佈的應用程序消息可能在到客戶端的躍點上丟失,但是服務器不應該發送該消息的副本。發佈到同一主題的QoS 1消息可能在傳輸到該客戶端時丟失或重複。
非規範性評論
在QoS 2上訂閱主題過濾器相當於說“我希望在發佈它們的QoS上接收與該過濾器匹配的消息”。這意味着發佈者負責確定可以在其中傳遞消息的最大QoS,但是訂閱者能夠要求服務器將QoS降級爲更適合其使用的QoS。