MQTT V3.1.1 協議 規範

目錄

1.簡介

1.1術語

​1.2 數據表示

1.2.1 位

1.2.2整數數據值

1.2.3 UTF-8編碼的字符串

2 MQTT控制包格式

2.1 MQTT控制包的結構

2.2 固定報頭

2.2.1 MQTT控制報文類型

2.2.2 標誌

2.2.3剩餘長度

2.3 可變報頭

2.3.1 數據包標識符

2.4 有效載荷

3 MQTT控制包

3.1 CONNECT –客戶端請求與服務器的連接 

3.1.1 固定頭

3.1.2 可變頭

3.1.3 有效載荷

3.1.4 應答

3.2 CONNACK –確認連接請求

3.2.1 Fixed header

3.2.2 Variable header

3.2.3有效載荷

3.3 PUBLISH – 發佈消息

3.3.1 Fixed header

3.3.2  Variable header

3.3.3 Payload

3.3.4 Response

3.3.5 Actions

3.4 PUBACK –發佈確認

3.4.1 Fixed header

3.4.2 Variable header

3.4.3 Payload

3.4.4 Actions

3.5 PUBREC –發佈已接收(QoS 2已發佈,第1部分)

3.5.1 Fixed header

3.5.2 Variable header

3.5.3 Payload

3.5.4 Actions

3.6 PUBREL –發佈發佈(已收到QoS 2發佈,第2部分)

3.6.1 Fixed header

3.6.2 Variable header

3.6.3 Payload

3.6.4 Actions

3.7 PUBCOMP –完成發佈(已收到QoS 2發佈,第3部分)

 3.7.1 Fixed header

3.7.2 Variable header

3.7.3 Payload

3.7.4 Actions

3.8 SUBSCRIBE-訂閱主題

 3.8.1 Fixed header

3.8.2 Variable header

 3.8.3 Payload

3.8.4 Response

3.9 SUBACK –訂閱確認

3.9.1 Fixed header

3.9.2 Variable header

3.9.3 Payload

3.10 UNSUBSCRIBE–退訂主題

3.10.1 Fixed header

3.10.2 Variable header

3.10.3 Payload

3.10.4 Response

3.11 UNSUBACK-取消訂閱確認

3.11.1 Fixed header

3.11.2 Variable header

3.11.3 Payload

3.12 PINGREQ – PING請求

3.12.1 Fixed header

3.12.2 Variable header

3.12.3 Payload

 3.12.4 Response

3.13 PINGRESP – PING響應

3.13.1 Fixed header

3.13.2 Variable header

3.13.3 Payload

3.14 DISCONNECT –斷開通知

3.14.1 Fixed header

3.14.2 Variable header

3.14.3 Payload

3.14.4 Response

4   Operational behavior

4.1 Storing state

4.1.1非規範說明示例

4.2網絡連接

4.3服務質量級別和協議流

4.3.1 QoS 0: At most once delivery

4.3.2 QoS 1: At least once delivery

4.3.3 QoS 2: Exactly once delivery

4.4 Message delivery retry(消息重傳)

4.5 Message receipt(消息回執)

4.6 Message ordering(消息排序)

4.7 Topic Names and Topic Filters(主題名稱和主題過濾器)

4.7.1 Topic wildcards(主題通配符)

4.7.2  Topics beginning with $(以$開頭的主題)

4.7.3 Topic semantic and usage(主題的語法和用法)

4.8 Handling errors(錯誤處理)

5 安全

5.1 簡介

5.2 MQTT解決方案:安全性和認證

5.3 輕量級加密和受約束的設備

5.4實施說明

5.4.1 服務器對客戶端的身份驗證

5.4.2 服務器對客戶端的授權

5.4.3 客戶端對服務器的身份驗證

5.4.4 應用消息和控制包的完整性

5.4.5 應用消息和控制包的私有性

5.4.6 不可拒絕的消息傳輸

5.4.7 檢測客戶端和服務器的危害

5.4.8 檢測異常行爲

5.4.9 其他安全考慮

5.4.10 Use of SOCKS

5.4.11安全配置文件

6   Using WebSocket as a network transport

6.1 IANA注意事項

7 一致性

7.1一致性指標

7.1.1 MQTT服務器

7.1.2 MQTT客戶端

8.  Wirshark 抓包截圖


1.簡介

1.1術語

在本規範中,關鍵字“必須”,“不得”,“必須”,“應”,“應不”,“應”,“不應”,“建議”,“可以”和“可選”是 如IETF RFC 2119 [RFC2119]中所述進行解釋。

網絡連接(Network Connection):

由MQTT使用的基礎傳輸協議提供的構造。

  • 將客戶端連接到服務器。

 

  • ·它提供了在兩個方向上發送有序的無損字節流的方法。

有關示例,請參見第4.2節。

應用信息(Application Message

MQTT協議通過網絡爲應用程序承載的數據。當MQTT傳輸應用程序消息時,它們具有關聯的服務質量和主題名稱。

客戶端Client):

使用MQTT的程序或設備。客戶端始終建立與服務器的網絡連接。它可以

  • 發佈其他客戶端可能感興趣的應用程序消息。
  • 訂閱以請求有興趣接收的應用程序消息。
  • 退訂以刪除對應用程序消息的請求。
  • 斷開與服務器的連接。

服務器(Server

一種程序或設備,充當發佈應用程序消息的客戶端和進行訂閱的客戶端之間的中介。服務器

  • 接受來自客戶端的網絡連接。
  • 接受客戶端發佈的應用程序消息。
  • 處理來自客戶端的訂閱和取消訂閱請求。
  • 轉發與客戶端訂閱匹配的應用程序消息。

訂閱(Subscription

訂閱包括主題過濾器和最大QoS。訂閱與單個會話關聯。一個會話可以包含多個訂閱。會話中的每個訂閱都有一個不同的主題過濾器。

主題名稱(Topic Name)

附加到應用程序消息的標籤,該標籤與服務器已知的訂閱相匹配。服務器將應用程序消息的副本發送給具有匹配訂閱的每個客戶端。

主題過濾器(Topic Filter)

訂閱中包含的一種表達,表示對一個或多個主題感興趣。主題過濾器可以包含通配符。

會話(Session)

客戶端和服務器之間的狀態交互。某些會話的持續時間僅與網絡連接的時間相同,而其他會話則可以跨越客戶端和服務器之間的多個連續的網絡連接。

MQTT控制數據包(MQTT Control Packet:)

通過網絡連接發送的信息包。 MQTT規範定義了十四種不同類型的控制包,其中一種(發佈包)用於傳達應用消息。

 

1.2 數據表示

1.2.1 位

字節中的位標記爲7到0。位號7是最高有效位,最低位是0。

1.2.2整數數據值

整數數據值,16位按大端順序:

高位字節位於低位字節之前。 這意味着在網絡上將16位字表示爲最高有效字節(MSB),然後是最低有效字節(LSB)。

1.2.3 UTF-8編碼的字符串

稍後描述的控制包中的文本字段被編碼爲UTF-8字符串。 UTF-8 [RFC3629]是Unicode [Unicode]字符的有效編碼,可優化ASCII字符的編碼以支持基於文本的通信。

這些字符串中的每個字符串都有兩個字節的長度字段作爲前綴,該字段給出了UTF-8編碼的字符串本身的字節數,如下圖1.1所示。 因此,在這些UTF-8編碼的字符串組件之一中可以傳遞的字符串的大小受到限制。 您不能使用編碼超過65535個字節的字符串。

除非另有說明,否則所有UTF-8編碼的字符串的長度都可以在0到65535字節之間。

圖1.1 Structure of UTF-8 encoded strings

Bit

7

6

5

4

3

2

1

0

byte 1

String length MSB

byte 2

String length LSB

byte 3 ….

UTF-8 Encoded Character Data, if length > 0.

UTF-8編碼的字符串中的字符數據必須按照Unicode規範[Unicode]的規定,採用格式正確的UTF-8,並在RFC 3629 [RFC3629]中進行重述。 特別是,此數據不得包含U + D800和U + DFFF之間的代碼點編碼。 如果服務器或客戶端收到包含格式錯誤的UTF-8的控制包,則必須關閉網絡連接。

UTF-8編碼的字符串不得包含空字符U + 0000的編碼。 如果接收方(服務器或客戶端)接收到包含U + 0000的控制包,則必須關閉網絡連接

數據不應包含下面列出的Unicode [Unicode]代碼點的編碼。 如果接收方(服務器或客戶端)接收到包含任何接收方的控制包,則可以關閉網絡連接

U + 0001..U + 001F控制字符

U + 007F..U + 009F控制字符

Unicode規範[Unicode]中定義的代碼點爲非字符(例如U + 0FFFF)

UTF-8編碼的序列0xEF 0xBB 0xBF始終應解釋爲表示U + FEFF(“零寬度無間斷空格”),無論它出現在字符串中什麼地方,並且一定不要被數據包接收器跳過或剝離。

2 MQTT控制包格式

2.1 MQTT控制包的結構

MQTT協議通過以定義的方式交換一系列MQTT控制包來工作。 本節介紹這些數據包的格式。

MQTT控制包最多由三部分組成,始終按以下順序排列,如圖2.1-MQTT控制包的結構所示。

Figure 2.1 – Structure of an MQTT Control Packet
固定報頭(Fixed header), present in all MQTT Control Packets
可變報頭(Variable header), present in some MQTT Control Packets
有效載荷(Payload), present in some MQTT Control Packets

2.2 固定報頭

每個MQTT控制包都包含一個固定的報頭。 圖2.2-固定標頭格式說明了固定標頭格式。

圖2.2 固定報文頭格式
Bit 7 6 5 4 3 2 1 0

byte 1

MQTT 控制報文的類型

控制報文類型的標誌位

byte 2…

剩餘長度

2.2.1 MQTT控制報文類型

位置:字節1,位7-4。

表示爲4位無符號值的值在表2.1-控制包類型中列出。

Table 2.1 - Control packet types

Reserved

0

禁止

保留

CONNECT

1

Client to Server

客戶端請求連接服務器

CONNACK

2

Server to Client

連接報文確認

PUBLISH

3

Client to Server

          or

Server to Client

發佈消息

PUBACK

4

Client to Server

          or

Server to Client

消息發佈收到確認(QoS1)

PUBREC

5

Client to Server

          or

Server to Client

發佈收到 (QoS2)

PUBREL

6

Client to Server

          or

Server to Client

發佈釋放(QoS2)

PUBCOMP

7

Client to Server

          or

Server to Client

發佈完成(QoS2)

SUBSCRIBE

8

Client to Server

客戶端訂閱請求

SUBACK

9

Server to Client

訂閱請求報文確認

UNSUBSCRIBE

10

Client to Server

客戶端取消訂閱請求

UNSUBACK

11

Server to Client

取消訂閱報文確認

PINGREQ

12

Client to Server

心跳請求

PINGRESP

13

Server to Client

心跳響應

DISCONNECT

14

Client to Server

客戶端斷開連接

Reserved

15

Forbidden

系統保留

2.2.2 標誌

固定報頭中字節1的其餘[3-0]位包含特定於每種MQTT控制數據包類型的標誌,如下面的表2.2-標誌位中所列。

如果在表2.2-標誌位中將標誌位標記爲“保留”,則保留該標誌位以備將來使用,並且必須將其設置爲該表[MQTT-2.2.2-1]中列出的值。 如果收到無效標誌,則接收方必須關閉網絡連接[MQTT-2.2.2-2]。 有關處理錯誤的詳細信息,請參見第4.8節。

Table 2.2 - Flag Bits

Control Packet

Fixed header flags

Bit 3

Bit 2

Bit 1

Bit 0

CONNECT

Reserved

0

0

0

0

CONNACK

Reserved

0

0

0

0

PUBLISH

Used in MQTT 3.1.1

DUP1

QoS2

QoS2

RETAIN3

PUBACK

Reserved

0

0

0

0

PUBREC

Reserved

0

0

0

0

PUBREL

Reserved

0

0

1

0

PUBCOMP

Reserved

0

0

0

0

SUBSCRIBE

Reserved

0

0

1

0

SUBACK

Reserved

0

0

0

0

UNSUBSCRIBE

Reserved

0

0

1

0

UNSUBACK

Reserved

0

0

0

0

PINGREQ

Reserved

0

0

0

0

PINGRESP

Reserved

0

0

0

0

DISCONNECT

Reserved

0

0

0

0

DUP =重複發送發佈控制包

QoS =發佈服務質量

RETAIN = PUBLISH保留標誌

有關發佈控制包中DUP,QoS和RETAIN標誌的說明,請參見第3.3.1節。

注:事實上,除了PUBLISH類型報文以外,其他報文的標誌位均爲系統保留,PUBLISH 報文的第一字節bit3 是控制報文的重複分發標誌(DUP),bit1-bit2 是服務質量等級,bit0 是PUBLISH 報文的保留標誌,用於標識PUBLISH 是否保留,當客戶端發送一個PUBLISH 消息到服務器,如果保留標識位置1,那麼服務器應該保留這條消息,當一個新的訂閱者訂閱這個主題的時候,最後保留的主題消息應被髮送到新訂閱的用戶。

2.2.3剩餘長度

位置:從字節2開始。

剩餘長度是當前數據包中剩餘的字節數,包括變量頭和有效載荷中的數據。 剩餘長度不包括用於編碼剩餘長度的字節。

剩餘長度使用可變長度編碼方案進行編碼,該方案使用單個字節表示最大127的值。較大的值按以下方式處理。 每個字節的最低有效七位對數據進行編碼,而最高有效位用於指示表示中有後續字節。 因此,每個字節編碼128個值和一個“連續位”。 剩餘長度字段中的最大字節數爲4。

2.3 可變報頭

某些類型的MQTT控制包包含可變報頭組件。 它位於固定標頭和有效負載之間。 可變報頭的內容取決於數據包類型。 可變報頭的數據包標識符字段在幾種數據包類型中是常見的。 

2.3.1 數據包標識符

許多控制數據包類型的可變報頭組件都包含一個2字節的數據包標識符字段。 這些控制數據包是PUBLISH(QoS> 0),PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCRIBE和UNSUBACK。

SUBSCRIBE,UNSUBSCRIBE和PUBLISH(在QoS> 0的情況下)控制分組必須包含一個非零的16位分組標識符[MQTT-2.3.1-1]。

每次客戶發送一個新的這些類型之一的數據包,它必須給它分配一個當前未使用的數據包標識符[MQTT-2.3.1-2]。

如果客戶端重新發送一個特定的控制包,則它必須在該包的後續重新發送中使用相同的包標識符。 在客戶端處理了相應的確認數據包後,數據包標識符就可以重用。 在QoS 1 PUBLISH的情況下,這是對應的PUBACK; 在QoS 2的情況下,它是PUBCOMP。

對於SUBSCRIBE或UNSUBSCRIBE,它是對應的SUBACK或UNSUBACK [MQTT-2.3.1-3]。

當服務器發送QoS> 0 [MQTT-2.3.1-4]的發佈消息時,這些條件也適用於服務器。 

如果發佈的包的QoS值設置爲0 [MQTT-2.3.1-5],則它絕對不能包含包標識符。

PUBACK,PUBREC或PUBREL數據包必須包含與最初發送的PUBLISH數據包相同的數據包標識符[MQTT-2.3.1-6]。

同樣,SUBACK和UNSUBACK必須包含分別在相應的SUBSCRIBE和UNSUBSCRIBE數據包[MQTT-2.3.1-7]中使用的數據包標識符。

表2.5-包含數據包標識符的控制數據包中列出了需要數據包標識符的控制數據包。

客戶端和服務器彼此獨立地分配分組標識符。 結果,客戶端服務器對可以使用相同的數據包標識符參與併發消息交換。

例子:

客戶端可以發送帶有數據包標識符0x1234的PUBLISH數據包,然後在接收到發送的PUBLISH消息的PUBACK之前,從其服務器接收另一個帶有Packet Identifier 0x1234的PUBLISH消息。

2.4 有效載荷

如第3章所述,某些MQTT控制數據包包含有效載荷作爲數據包的最後部分。對於發佈數據包,這是應用程序消息。 表2.6-包含有效負載的控制包列出了需要有效負載的控制包。 

3 MQTT控制包

3.1 CONNECT –客戶端請求與服務器的連接 

客戶端與服務器建立網絡連接後,從客戶端發送至服務器的第一個數據包必須爲CONNECT數據包[MQTT-3.1.0-1]。

客戶端只能通過網絡連接發送一次CONNECT數據包。 服務器必須處理從客戶端發送的第二個CONNECT數據包,作爲協議違規,並斷開客戶端[MQTT-3.1.0-2]的連接。 有關處理錯誤的信息,請參見第4.8節。

有效負載包含一個或多個編碼字段。 它們爲客戶端指定唯一的客戶端標識符,“遺囑”主題,“遺囑消息”,“用戶名”和“密碼”。 除客戶端標識符外,其餘是可選的,它們的存在是根據變量頭中的標誌確定的。

3.1.1 固定頭

剩餘長度字段

剩餘長度是變量頭的長度(10個字節)加上有效負載的長度。 它按照第2.2.3節中所述的方式進行編碼。 

3.1.2 可變頭

CONNECT數據包的變量頭按以下順序包含四個字段:協議名稱,協議級別,連接標誌和保持活動。

3.1.2.1 協議名稱

協議名稱是UTF-8編碼的字符串,代表協議名稱“ MQTT”,大寫,如下所示。 字符串,其偏移量和長度將不會在MQTT規範的未來版本中更改。 

如果協議名稱不正確,服務器可以斷開客戶端的連接,或者可以繼續按照其他規範處理CONNECT數據包。 在後一種情況下,服務器不得根據本規範[MQTT-3.1.2-1]繼續處理CONNECT數據包。

注:數據包檢查器(例如防火牆)可以使用協議名稱來標識MQTT通信。

3.1.2.2 協議級別

8位無符號值,表示客戶端使用的協議的修訂級別。 協議版本3.1.1的“協議級別”字段的值爲4(0x04)。 服務器必須以CONNACK返回碼0x01(不可接受的協議級別)響應CONNECT數據包,然後如果服務器[MQTT-3.1.2-2]不支持協議級別,則斷開客戶端的連接。 

3.1.2.3 連接標誌

連接標誌字節包含許多參數,這些參數指定MQTT連接的行爲。 它還指示有效載荷中字段的存在或不存在。

服務器必須確認CONNECT控制包中的保留標誌設置爲零,如果不爲零,則斷開客戶端的連接[MQTT-3.1.2-3]。

3.1.2.4 清除會話

位置:連接標誌字節的位1。

該位指定會話狀態的處理。

客戶端和服務器可以存儲會話狀態,以使可靠的消息傳遞能夠在一系列網絡連接中繼續進行。 該位用於控制會話狀態的生存期。

如果CleanSession設置爲0,則服務器務必根據當前會話的狀態(由客戶端標識符標識)恢復與客戶端的通信。 如果沒有與客戶端標識符相關的會話,則服務器必須創建一個新的會話。 客戶端和服務器斷開連接後,客戶端和服務器必須存儲會話[MQTT-3.1.2-4]。

在將CleanSession設置爲0的會話斷開連接後,服務器務必將與斷開連接時客戶端具有的所有訂閱相匹配的其他QoS 1和QoS 2消息作爲會話狀態[MQTT-3.1.2-5]。 它還可以存儲滿足相同條件的QoS 0消息。

如果CleanSession設置爲1,則客戶端和服務器務必丟棄任何先前的會話並開始一個新的會話。 該會話持續到網絡連接。 與該會話相關的狀態數據不得在任何後續會話[MQTT-3.1.2-6]中重用。

客戶端中的會話狀態包括:

  • ·已發送到服務器但尚未完全確認的QoS 1和QoS 2消息。
  • ·已從服務器收到但未完全確認的QoS 2消息。

服務器中的會話狀態包括:

  • ·會話的存在,即使會話的其餘狀態爲空。
  • ·客戶的訂閱。
  • ·已發送到客戶端但尚未完全確認的QoS 1和QoS 2消息。
  • ·QoS 1和QoS 2消息等待傳輸到客戶端。
  • ·已經從客戶端收到但尚未完全確認的QoS 2消息。
  • ·(可選)QoS 0消息等待傳輸到客戶端。

保留的消息不構成服務器中會話狀態的一部分,在會話結束時不得刪除它們[MQTT-3.1.2.7]。

3.1.2.5 Will Flag (遺囑標誌)

位置:連接標誌的第2位。

如果將Will Flag設置爲1,則表示如果接受了連接請求,則Will消息必須存儲在服務器上並與網絡連接關聯。 除非網絡在收到DISCONNECT數據包[MQTT-3.1.2-8]後刪除了意願消息,否則必須在隨後關閉網絡連接時發佈遺囑消息。

發佈遺囑消息的情況包括但不限於:

  • 服務器檢測到I / O錯誤或網絡故障。
  • 客戶端在保持活動時間內無法通信。
  •  客戶端未先發送DISCONNECT數據包即可關閉網絡連接。
  •  由於協議錯誤,服務器關閉了網絡連接。

如果將Will Flag設置爲1,則服務器將使用Connect Flag中的Will QoS和Will Retain字段,並且有效負載中必須存在Will Topic和Will Message字段[MQTT-3.1.2-9]。

一旦發佈了Will消息,或者服務器從客戶端[MQTT-3.1.2-10]接收到DISCONNECT數據包,則必須將Will消息從服務器中的已存儲會話狀態中刪除。

如果將Will標誌設置爲0,則必須將連接標誌中的Will QoS和Will Retain字段設置爲零,並且在有效載荷[MQTT-3.1.2-11]中不得出現Will Topic和Will Message字段。

如果將Will標誌設置爲0,則在此網絡連接結束時[MQTT-3.1.2-12]不得發佈Will消息。

服務器應該及時發佈遺囑消息。 在服務器關閉或失敗的情況下,服務器可以將Will Messages的發佈推遲到隨後的重啓。 如果發生這種情況,則在服務器出現故障與發佈Will消息之間可能會有延遲。

3.1.2.6 Will QoS(遺囑消息服務質量等級)

位置:連接標誌的第4位和第3位。

這兩位指定發佈遺囑消息時要使用的QoS級別。

如果將Will Flag設置爲0,則Will QoS必須設置爲0(0x00)[MQTT-3.1.2-13]。

如果將Will Flag設置爲1,則Will QoS的值可以爲0(0x00),1(0x01)或2(0x02)。 不得爲3(0x03)[MQTT-3.1.2-14]。

3.1.2.7 Will Retain(遺囑保留)

位置:連接標誌的第5位。

該位指定在發佈遺囑消息時是否保留該遺囑消息。

如果Will flag 設置爲0,則Will Retain 務必設置爲0 [MQTT-3.1.2-15]。
如果將意志標記設置爲1:
     如果Will Retain設置爲0,則服務器必須發佈Will消息作爲非保留消息[MQTT-3.1.2-16]。
     如果Will Retain設置爲1,則服務器必須發佈Will消息作爲保留消息[MQTT-3.1.2-17]。

3.1.2.8 User Name Flag(用戶名標誌)

位置:連接標誌的第7位。

如果用戶名標誌設置爲0,則有效載荷[MQTT-3.1.2-18]中絕對不能存在用戶名。

如果用戶名標誌設置爲1,則用戶名必須出現在有效載荷[MQTT-3.1.2-19]中。

3.1.2.9 Password Flag(密碼標誌)

位置:連接標誌字節的第6位。

如果密碼標誌設置爲0,則有效負載[MQTT-3.1.2-20]中絕對不能存在密碼。

如果密碼標誌設置爲1,則有效負載[MQTT-3.1.2-21]中必須存在密碼。

如果用戶名標誌設置爲0,則密碼標誌必須設置爲0 [MQTT-3.1.2-22]。

3.1.2.10 Keep Alive(保持連接)

保持活動狀態是以秒爲單位的時間間隔。 16位表示,它是客戶端完成發送一個控制數據包的時間點與開始發送下一個控制數據包的時間之間允許的最大時間間隔。 客戶有責任確保發送的控制數據包之間的間隔不超過“保持活動”值。 在沒有發送任何其他控制分組的情況下,客戶端必須發送PINGREQ分組[MQTT-3.1.2-23]。

客戶端可以隨時發送PINGREQ,而無需考慮“保持活動”值,並可以使用PINGRESP來確定網絡和服務器是否正常工作。

如果“保持活動”值不爲零,並且服務器在“保持活動”時間的一半時間內未收到來自客戶端的控制包,則它必須斷開與客戶端的網絡連接,就像網絡出現故障一樣[MQTT-3.1.2-24。

如果客戶端在發送PINGREQ後的合理時間內未收到PINGRESP數據包,則應關閉與服務器的網絡連接。

保持活動值爲零(0)具有關閉保持活動機制的作用。 這意味着,在這種情況下,不需要服務器以不活動爲由斷開客戶端連接。請注意,無論該客戶端提供的“保持活動”值如何,都允許服務器隨時斷開其確定爲不活動或無響應的客戶端的連接。

3.1.2.11 可變標頭示例

3.1.3 有效載荷

CONNECT數據包的有效負載包含一個或多個帶前綴的字段,這些字段的存在由變量頭中的標誌確定。 這些字段(如果存在)必須按客戶端標識符,主題,遺囑消息,用戶名,密碼[MQTT-3.1.3-1]的順序顯示。

3.1.3.1 Client Identifier (客戶端標識符)

客戶端標識符(ClientId)標識服務器的客戶端。 每個連接到服務器的客戶端都有一個唯一的ClientId。 客戶端和服務器必須使用ClientId來識別它們與客戶端和服務器之間的MQTT會話有關的狀態[MQTT-3.1.3-2]。

客戶端標識符(ClientId)必須存在,並且必須是CONNECT數據包有效載荷[MQTT-3.1.3-3]中的第一個字段。

ClientId必須是第1.5.3節[MQTT-3.1.3-4]中定義的UTF-8編碼的字符串。服務器必須允許長度在1到23個UTF-8編碼字節之間且僅包含字符的ClientId。

服務器可以允許包含超過23個編碼字節的ClientId。

服務器可以允許客戶端提供一個長度爲零字節的ClientId,但是如果這樣做,則服務器必須將其視爲特殊情況,併爲該客戶端分配一個唯一的ClientId。 然後,它必須處理CONNECT包,就好像客戶端已經提供了唯一的ClientId [MQTT-3.1.3-6]。

如果客戶端提供了一個零字節的ClientId,則客戶端還必須將CleanSession設置爲1 [MQTT-3.1.3-7]。

如果客戶端提供一個零字節的ClientId且CleanSession設置爲0,則服務器務必以CONNACK返回碼0x02(拒絕標識符)響應CONNECT數據包,然後關閉網絡連接[MQTT-3.1.3-8]。

如果服務器拒絕ClientId,則它必須以CONNACK返回碼0x02(拒絕標識符)響應CONNECT數據包,然後關閉網絡連接[MQTT-3.1.3-9]。

3.1.3.2 Will Topic(遺囑主題)

如果將Will Flag設置爲1,則Will Topic是有效負載中的下一個字段。 遺囑主題必須是第1.5.3節[MQTT-3.1.3-10]中定義的UTF-8編碼的字符串。

3.1.3.3 Will Message(遺囑信息)

如果將Will Flag設置爲1,則Will Message是有效負載中的下一個字段。 遺囑信息定義了要發佈到遺囑主題的應用程序消息,如第3.1.2.5節中所述。 該字段由兩個字節的長度組成,後跟表示爲零個或多個字節的序列的Will消息的有效負載。 長度給出了後續數據中的字節數,並且不包括長度本身佔用的2個字節。

3.1.3.4 User Name

如果用戶名標誌設置爲1,則這是有效負載中的下一個字段。 用戶名務必是第1.5.3節[MQTT-3.1.3-11]中定義的UTF-8編碼的字符串。 服務器可以使用它進行身份驗證和授權。

3.1.3.5 Password

如果密碼標誌設置爲1,則這是有效負載中的下一個字段。 密碼字段包含0到65535字節的二進制數據,其前綴爲兩個字節的長度字段,該字段指示二進制數據使用的字節數(它不包括長度字段本身佔用的兩個字節)。

3.1.4 應答

注意,服務器可以在同一TCP端口或其他網絡端點上支持多種協議(包括該協議的早期版本)。 如果服務器確定該協議爲MQTT 3.1.1,則它將按照以下方式驗證連接嘗試。

1.如果服務器在建立網絡連接後的合理時間內未收到CONNECT數據包,則服務器應關閉連接。

2.服務器必須驗證CONNECT數據包是否符合第3.1節的規定,如果不符合[MQTT-3.1.4-1],則在不發送CONNACK的情況下關閉網絡連接。

3.服務器可以檢查CONNECT數據包的內容是否滿足任何進一步的限制,並可以執行身份驗證和授權檢查。 如果這些檢查中的任何一個失敗,它應該發送一個適當的帶有非零返回碼的CONNACK響應,如3.2節所述,並且必須關閉網絡連接。

如果驗證成功,則服務器將執行以下步驟。

1.如果ClientId代表已經連接到服務器的客戶端,則服務器必須斷開現有客戶端的連接[MQTT-3.1.4-2]。

2.服務器必須執行第3.1.2.4節[MQTT-3.1.4-3]中所述的CleanSession處理。

3.服務器必須用包含零返回碼[MQTT-3.1.4-4]的CONNACK包確認CONNECT包。

4.開始傳遞消息並保持實時監視。

允許客戶端在發送CONNECT數據包後立即發送其他控制數據包; 客戶端無需等待CONNACK數據包從服務器到達。 如果服務器拒絕CONNECT,則它不得在CONNECT數據包[MQTT-3.1.4-5]之後處理客戶端發送的任何數據。

3.2 CONNACK –確認連接請求

CONNACK數據包是服務器響應從客戶端收到的CONNECT數據包而發送的數據包。 從服務器發送到客戶端的第一個數據包必須是CONNACK數據包[MQTT-3.2.0-1]。

如果客戶端在合理的時間內沒有收到來自服務器的CONNACK數據包,則客戶端應關閉網絡連接。 “合理的”時間量取決於應用程序的類型和通信基礎結構。

3.2.1 Fixed header

剩餘長度字段

這是變量頭的長度。 對於CONNACK數據包,其值爲2。 

3.2.2 Variable header

3.2.2.1 Connect Acknowledge Flags 

字節1是“連接確認標誌”。 位7-1是保留位,必須設置爲0。位0(SP1)是會話存在標誌。

3.2.2.2 Session Present

位置:連接確認標誌的位0。

如果服務器接受CleanSession設置爲1的連接,則除了在CONNACK數據包中設置零返回碼[MQTT-3.2.2-1]之外,服務器還必須在CONNACK數據包中將Session Present設置爲0。

如果服務器接受CleanSession設置爲0的連接,則在Session Present中設置的值取決於Server是否已經爲提供的客戶端ID存儲了Session狀態。 如果服務器已存儲會話狀態,則必須在CONNACK數據包[MQTT-3.2.2-2]中將會話存在設置爲1。 如果服務器尚未存儲會話狀態,則必須在CONNACK數據包中將會話存在設置爲0。 這是在CONNACK數據包[MQTT-3.2.2-3]中設置零返回碼的補充。

會話存在標誌使客戶端能夠確定客戶端和服務器是否對是否已經存儲了會話狀態具有一致的視圖。

一旦會話的初始設置完成,具有存儲會話狀態的客戶端將期望服務器保持其存儲會話狀態。 如果客戶端從服務器收到的Session Present的值與預期不符,則客戶端可以選擇繼續進行會話還是斷開連接。 通過斷開連接,將Clean Session設置爲1並再次斷開連接,客戶端可以丟棄客戶端和服務器上的會話狀態。

如果服務器發送包含非零返回碼的CONNACK數據包,則必須將會話存在設置爲0 [MQTT-3.2.2-4]。

3.2.2.3 Connect Return code

可變報頭中的字節2。

表3.1 –連接返回碼值中列出了一個字節的無符號連接返回碼字段的值。 如果服務器接收到格式正確的CONNECT數據包,但是服務器由於某種原因無法對其進行處理,則服務器應嘗試從該表發送包含適當的非零連接返回代碼的CONNACK數據包。 如果服務器發送包含非零返回碼的CONNACK數據包,則它必須關閉網絡連接[MQTT-3.2.2-5]。

3.2.3有效載荷

CONNACK數據包沒有有效負載。 

3.3 PUBLISH – 發佈消息

PUBLISH控制包從客戶端發送到服務器,或者從服務器發送到客戶端,以傳輸應用程序消息。

3.3.1 Fixed header

3.3.1.1 DUP

位置:字節1,位3。

如果DUP標誌設置爲0,則表明這是客戶端或服務器第一次嘗試發送此MQTT PUBLISH數據包。 如果DUP標誌設置爲1,則表明這可能是較早嘗試發送數據包的重新傳遞。

當客戶端或服務器嘗試重新發送發佈包[MQTT-3.3.1.-1]時,DUP標誌必須由客戶端或服務器設置爲1。 對於所有QoS 0消息[MQTT-3.3.1-2],DUP標誌必須設置爲0。

服務器將PUBLISH數據包發送給訂閱者時,不會傳播來自傳入PUBLISH數據包的DUP標誌的值。 傳出的PUBLISH包中的DUP標誌獨立於傳入的PUBLISH包設置,其值必須僅由傳出的PUBLISH包是否是重傳來確定[MQTT-3.3.1-3]。

3.3.1.2 QoS

位置:字節1,位2-1。

該字段指示用於傳遞應用消息的保證級別。 下表3.2-QoS定義中列出了QoS級別。

PUBLISH數據包絕不能將兩個QoS都設置爲1。如果服務器或客戶端收到兩個QoS位都被設置爲1的PUBLISH包,則必須關閉網絡連接[MQTT-3.3.1-4]。

3.3.1.3 RETAIN (保留)

位置:字節1,位0。

如果RETAIN標誌設置爲1,則在客戶端發送給服務器的PUBLISH數據包中,服務器必須存儲應用消息及其QoS,以便可以將其傳遞給訂閱與其主題名稱[MQTT-3.3.1-5。 建立新的訂閱後,每個匹配主題名稱上的最後保留消息(如有)必須發送給訂閱者[MQTT-3.3.1-6]。 如果服務器收到RETAIN標誌設置爲1的QoS 0消息,則它必須丟棄先前爲該主題保留的任何消息。 它應該將新的QoS 0消息存儲爲該主題的新保留消息,但可以選擇隨時將其丟棄-如果發生這種情況,將沒有該主題的保留消息[MQTT-3.3.1-7]。 有關存儲狀態的更多信息,請參見第4.1節。

當向客戶端發送發佈數據包時,如果由於客戶端[MQTT-3.3.1-8]進行了新的訂閱而發送了消息,則服務器必須將RETAIN標誌設置爲1。 當將PUBLISH數據包發送到客戶端時,它必須將RETAIN標誌設置爲0,因爲它與已建立的訂閱匹配,無論在接收到的消息中如何設置該標誌[MQTT-3.3.1-9]。

服務器將按正常方式處理將RETAIN標誌設置爲1且負載爲零字節的PUBLISH數據包,並通過與主題名稱匹配的預訂將其發送給客戶端。 此外,必須刪除具有相同主題名稱的任何現有保留消息,並且該主題的任何將來的訂閱者都不會收到保留消息[MQTT-3.3.1-10]。 “正常”表示在現有客戶端收到的消息中未設置RETAIN標誌。 零字節保留消息一定不能作爲保留消息存儲在服務器[MQTT-3.3.1-11]上。

如果RETAIN標誌爲0,則在客戶端發送給服務器的PUBLISH數據包中,服務器不得存儲該消息,並且不得刪除或替換任何現有的保留消息[MQTT-3.3.1-12]。

當發佈者不定期地發送狀態消息時,保留消息很有用。 新訂戶將收到最新狀態。

剩餘長度字段
         這是可變報頭的長度加上有效負載的長度。

3.3.2  Variable header

變量頭按順序包含以下字段:主題名稱,數據包標識符。

3.3.2.1 Topic Name

主題名稱標識有效載荷數據發佈到的信息通道。

主題名稱必須作爲PUBLISH Packet Variable標頭中的第一個字段出現。 它必須是第1.5.3節中定義的UTF-8編碼的字符串[MQTT-3.3.2-1]。

PUBLISH數據包中的主題名稱不得包含通配符[MQTT-3.3.2-2]。

服務器發送給訂閱客戶端的PUBLISH數據包中的主題名稱必須根據第4.7節[MQTT-3.3.2-3]中定義的匹配過程與訂閱的主題過濾器匹配。 但是,由於允許服務器覆蓋主題名稱,因此它可能與原始PUBLISH數據包中的主題名稱不同。

3.3.2.2 Packet Identifier

數據包標識符字段僅出現在QoS級別爲1或2的PUBLISH數據包中。第2.3.1節提供了有關數據包標識符的更多信息。

3.3.2.3 Variable header non normative example

3.3.3 Payload

有效負載包含正在發佈的應用程序消息。 數據的內容和格式是特定於應用程序的。

有效負載的長度可以通過從固定標頭中的“剩餘長度”字段中減去變量標頭的長度來計算。 PUBLISH數據包包含零長度的有效載荷是有效的。 

3.3.4 Response

PUBLISH數據包的接收者務必根據表3.4-由PUBLISH數據包[MQTT-3.3.4-1]中的QoS確定的預期發佈數據包響應。

3.3.5 Actions

客戶端使用PUBLISH數據包向服務器發送應用消息,以分發給具有匹配訂閱的客戶端。

服務器使用PUBLISH數據向每個具有匹配訂閱的客戶端發送應用程序消息。

當客戶使用包含通配符的主題過濾器進行訂閱時,客戶的訂閱可能會重疊,以便已發佈的郵件可能與多個過濾器匹配。 在這種情況下,服務器必須考慮所有匹配預訂的最大QoS [MQTT-3.3.5-1],將消息傳遞給客戶端。 另外,服務器可以傳送更多的消息副本,每個附加的匹配訂閱一個,並在每種情況下都遵守訂閱的QoS。

接收方接收到PUBLISH數據包時的操作取決於第4.3節中描述的QoS級別。

如果服務器實現未授權客戶端執行發佈; 它無法通知該客戶。 它必須根據正常的QoS規則做出肯定的確認,或者關閉網絡連接[MQTT-3.3.5-2]。

3.4 PUBACK –發佈確認

PUBACK數據包是對QoS級別爲1的PUBLISH數據包的響應。

3.4.1 Fixed header

剩餘長度字段

這是變量頭的長度。 對於PUBACK數據包,其值爲2。

3.4.2 Variable header

它包含來自正在確認的PUBLISH數據包的數據包標識符。

3.4.3 Payload

PUBACK數據包沒有有效負載。 

3.4.4 Actions

這在第4.3.2節中有完整描述。

3.5 PUBREC –發佈已接收(QoS 2已發佈,第1部分)

PUBREC數據包是對具有QoS 2的PUBLISH數據包的響應。它是QoS 2協議交換的第二個數據包。

3.5.1 Fixed header

剩餘長度字段

這是變量頭的長度。 對於PUBREC數據包,其值爲2。 

3.5.2 Variable header

變量頭包含來自正在確認的PUBLISH數據包的數據包標識符。

3.5.3 Payload

PUBREC數據包沒有有效負載。

3.5.4 Actions

這在第4.3.3節中有完整描述。

3.6 PUBREL –發佈發佈(已收到QoS 2發佈,第2部分)

PUBREL數據包是對PUBREC數據包的響應。 它是QoS 2協議交換的第三個數據包。 

3.6.1 Fixed header

PUBREL控制分組中固定報頭的比特3,2,1和0被保留,並且必須分別設置爲0,0,1和0。 服務器務必將任何其他值視爲格式錯誤,並關閉網絡連接[MQTT-3.6.1-1]。

Remaining Length field

This is the length of the variable header. For the PUBREL Packet this has the value 2.

3.6.2 Variable header

變量頭包含與正在確認的PUBREC數據包相同的數據包標識符。

 

3.6.3 Payload

The PUBREL Packet has no payload.


3.6.4 Actions

This is fully described in Section 4.3.3.

3.7 PUBCOMP –完成發佈(已收到QoS 2發佈,第3部分)

PUBCOMP數據包是對PUBREL數據包的響應。 它是QoS 2協議交換的第四個也是最後一個數據包。

 3.7.1 Fixed header

Remaining Length field

This is the length of the variable header. For the PUBCOMP Packet this has the value 2.

3.7.2 Variable header

變量頭包含與正在確認的PUBREL數據包相同的數據包標識符。

3.7.3 Payload

The PUBCOMP Packet has no payload.

3.7.4 Actions

This is fully described in Section 4.3.3.

3.8 SUBSCRIBE-訂閱主題

SUBSCRIBE數據包從客戶端發送到服務器以創建一個或多個訂閱。 每個訂閱都會註冊客戶對一個或多個主題的興趣。 服務器將PUBLISH數據包發送到客戶端,以轉發發佈到與這些訂閱匹配的主題的應用消息。 SUBSCRIBE數據包還(針對每個訂閱)指定服務器可以向客戶端發送應用消息的最大QoS。

 3.8.1 Fixed header

SUBSCRIBE控制包的固定報頭的比特3,2,1和0被保留,並且必須分別設置爲0,0,1和0。 服務器必須將任何其他值視爲格式錯誤,並關閉網絡連接[MQTT-3.8.1-1]。

Remaining Length field

This is the length of variable header (2 bytes) plus the length of the payload.

3.8.2 Variable header

可變報頭包含一個數據包標識符。 第2.3.1節提供了有關數據包標識符的更多信息。

3.8.2.1 Variable header non normative example

 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對被連續打包。

 當前版本的協議未使用“請求的QoS”字節的高6位。 它們保留供將來使用。 如果有效載荷中的保留位中的任何一個不爲零,或者QoS不是0.1或2 [MQTT-3-8.3-4],則服務器必須將SUBSCRIBE包視爲格式錯誤並關閉網絡連接。

3.8.3.1 Payload non normative example

3.8.4 Response

當服務器從客戶端收到一個SUBSCRIBE數據包時,服務器必須以SUBACK數據包[MQTT-3.8.4-1]作爲響應。 SUBACK數據包必須具有與其確認的SUBSCRIBE數據包相同的數據包標識符[MQTT-3.8.4-2]。 

在服務器發送SUBACK數據包之前,允許服務器開始發送與訂閱匹配的PUBLISH數據包。

如果服務器收到的SUBSCRIBE數據包包含與現有訂閱的主題過濾器相同的主題過濾器,則它必須用新的訂閱完全替換現有的訂閱。 新訂閱中的主題過濾器將與先前訂閱中的主題過濾器相同,儘管其最大QoS值可能不同。 必須重新發送與主題過濾器匹配的所有現有保留消息,但不得中斷髮布流程[MQTT-3.8.4-3]。

如果主題過濾器與任何現有訂閱的過濾器都不相同,則會創建一個新的訂閱併發送所有匹配的保留消息。

如果服務器接收到包含多個主題過濾器的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。

3.9 SUBACK –訂閱確認

服務器將SUBACK數據包發送給客戶端,以確認SUBSCRIBE數據包的接收和處理。

SUBACK數據包包含一個返回碼列表,這些返回碼指定了SUBSCRIBE請求的每個訂閱中授予的最大QoS級別。

3.9.1 Fixed header

Remaining Length field

This is the length of variable header (2 bytes) plus the length of the payload.

3.9.2 Variable header

可變報頭包含來自正在確認的SUBSCRIBE數據包的數據包標識符。 圖3.25-下方的可變標頭格式說明了可變標頭的格式。

3.9.3 Payload

有效負載包含返回碼列表。 每個返回碼對應於已確認的SUBSCRIBE數據包中的主題過濾器。 SUBACK數據包中返回碼的順序必須與SUBSCRIBE數據包[MQTT-3.9.3-1]中主題過濾器的順序相匹配。

允許的返回碼:

0x00-成功-最大QoS 0

0x01-成功-最大QoS 1

0x02-成功-最大QoS 2

0x80-失敗                                                  

除了0x00、0x01、0x02和0x80以外的SUBACK返回碼均保留,不得使用[MQTT-3.9.3-2]。

3.9.3.1 Payload non normative example

3.10 UNSUBSCRIBE–退訂主題

客戶端將UNSUBSCRIBE數據包發送到服務器,以取消訂閱主題。

3.10.1 Fixed header

UNSUBSCRIBE控制包的固定報頭的比特3,2,1和0被保留,並且必須分別設置爲0,0,1和0。 服務器務必將任何其他值視爲格式錯誤,並關閉網絡連接[MQTT-3.10.1-1]。

Remaining Length field

This is the length of variable header (2 bytes) plus the length of the payload.

3.10.2 Variable header

變量頭包含一個數據包標識符。 第2.3.1節提供了有關數據包標識符的更多信息。

3.10.3 Payload

UNSUBSCRIBE數據包的有效負載包含客戶端希望取消訂閱的主題過濾器列表。 UNSUBSCRIBE數據包中的主題過濾器必須是第1.5.3節中定義的,以UTF-8編碼的字符串,並連續包裝[MQTT-3.10.3-1]。

UNSUBSCRIBE數據包的有效載荷必須至少包含一個主題過濾器。 沒有有效載荷的UNSUBSCRIBE數據包違反協議[MQTT-3.10.3-2]。 有關處理錯誤的信息,請參見第4.8節。 

3.10.3.1 Payload non normative example

3.10.4 Response

必須將UNSUBSCRIBE數據包中提供的主題過濾器(無論是否包含通配符)逐個字符地與服務器爲客戶端保存的當前主題過濾器集進行比較。 如果任何過濾器完全匹配,則將刪除其擁有的訂閱,否則將不進行任何其他處理[MQTT-3.10.4-1]。 

如果服務器刪除訂閱:

  •      它必須停止添加任何新消息以傳遞給客戶端[MQTT-3.10.4-2]。
  •      它必須完成已經開始發送給客戶端[MQTT-3.10.4-3]的任何QoS 1或QoS 2消息的傳遞。
  •      它可以繼續傳遞任何緩衝的現有消息,以便傳遞給客戶端。

服務器必須通過發送一個UNSUBACK包來響應UNSUBSUBCRIBE請求。 UNSUBACK數據包必須具有與UNSUBSCRIBE數據包[MQTT-3.10.4-4]相同的數據包標識符。 即使沒有刪除任何主題訂閱,服務器也必須使用UNSUBACK [MQTT-3.10.4-5]進行響應。

如果服務器接收到包含多個主題過濾器的UNSUBSCRIBE數據包,則它必須像對待已接收到多個UNSUBSCRIBE數據包的序列一樣處理該數據包,只是它僅發送一個UNSUBACK響應[MQTT-3.10.4-6]。

3.11 UNSUBACK-取消訂閱確認

該UNSUBACK包由服務器發送給客戶確認收貨取消訂閱的包的。

3.11.1 Fixed header

Remaining Length field

This is the length of the variable header. For the UNSUBACK Packet this has the value 2.

3.11.2 Variable header

可變報頭包含正在確認的UNSUBSCRIBE數據包的數據包標識符。

3.11.3 Payload

The UNSUBACK Packet has no payload.

3.12 PINGREQ – PING請求

PINGREQ數據包從客戶端發送到服務器。 它可以用於:

  •      向服務器指示在沒有其他任何控制數據包從客戶端發送到服務器的情況下,客戶端處於活動狀態。
  •      請求服務器做出響應以確認其仍然有效。
  •      練習網絡以指示網絡連接處於活動狀態。

該數據包用於保持活動處理,有關更多詳細信息,請參見第3.1.2.10節。

3.12.1 Fixed header

3.12.2 Variable header

The PINGREQ Packet has no variable header.

3.12.3 Payload

The PINGREQ Packet has no payload.

 3.12.4 Response

服務器必須響應PINGREQ數據包[MQTT-3.12.4-1]發送PINGRESP數據包。

3.13 PINGRESP – PING響應

服務器響應PINGREQ數據包將PINGRESP數據包發送到客戶端。 它指示服務器還活着。

該數據包用於保持活動處理,有關更多詳細信息,請參見第3.1.2.10節。

3.13.1 Fixed header

 

3.13.2 Variable header

The PINGRESP Packet has no variable header.

3.13.3 Payload

The PINGRESP Packet has no payload.

3.14 DISCONNECT –斷開通知

DISCONNECT數據包是從客戶端發送到服務器的最終控制數據包。 這表明客戶端正在完全斷開連接。

3.14.1 Fixed header

服務器必須驗證保留位是否設置爲零,如果保留位不爲零,則斷開與客戶端的連接[MQTT-3.14.1-1]。 

3.14.2 Variable header

The DISCONNECT Packet has no variable header.

3.14.3 Payload

The DISCONNECT Packet has no payload.

3.14.4 Response

發送客戶端的DISCONNECT數據包後:

  •      必須關閉網絡連接[MQTT-3.14.4-1]。
  •      不得在該網絡連接[MQTT-3.14.4-2]上發送更多的控制包。

收到服務器斷開連接後:

  •      如第3.1.2.5節[MQTT-3.14.4-3]中所述,必須丟棄與當前連接關聯的任何Will Message而不發佈它。
  •      如果客戶端尚未關閉網絡連接,則應關閉網絡連接。

4   Operational behavior

4.1 Storing state

客戶端和服務器必須存儲會話狀態才能提供服務質量保證。 客戶端和服務器必須在整個會話期間存儲會話狀態[MQTT-4.1.0-1]。 會話必須至少持續有效的網絡連接[MQTT-4.1.0-2]。

保留的消息不構成服務器中會話狀態的一部分。 服務器應保留此類消息,直到被客戶端刪除爲止。

 

非規範性說明

  • 客戶端和服務器實現的存儲功能當然會在容量方面有所限制,並且可能會受管理策略的約束,例如在網絡連接之間存儲會話狀態的最長時間。管理員操作(包括對定義條件的自動響應)可導致丟棄存儲的會話狀態。這具有終止會話的作用。資源受限或其他操作原因可能會提示這些操作。謹慎評估客戶端和服務器的存儲功能以確保它們足夠。
  • 硬件或軟件故障可能會導致客戶端或服務器存儲的會話狀態丟失或損壞。
  • 服務器客戶端的正常運行可能意味着由於管理員操作,硬件故障或軟件故障而導致存儲狀態丟失或損壞。管理員操作可以是對定義條件的自動響應。資源受限或其他操作原因可能會提示這些操作。例如,服務器可能基於外部知識確定一條或多條消息不再可以傳遞給任何當前或將來的客戶端。
  • MQTT用戶應評估MQTT客戶端和服務器實現的存儲功能,以確保它們足以滿足其需求。

4.1.1非規範說明示例

例如,希望收集電錶讀數的用戶可能會決定他們需要使用QoS 1消息,因爲他們需要保護讀數免受網絡損失,但是,他們可能已經確定電源足夠可靠,以至於 客戶端和服務器可以存儲在易失性內存中,而不會造成太大的丟失風險。

相反,停車收費表支付應用程序提供商可能會決定在任何情況下都不會丟失支付消息,因此他們要求在通過網絡傳輸所有數據之前將所有數據強制寫入非易失性存儲器。

4.2網絡連接

MQTT協議需要基礎傳輸,該傳輸提供從客戶端到服務器以及從服務器到客戶端的有序無損字節流。

非規範性評論

如[RFC793]所定義,用於承載MQTT 3.1的傳輸協議是TCP / IP。 TCP / IP可以用於MQTT 3.1.1。 以下內容也適用:

  • TLS [RFC5246]
  • WebSocket [RFC6455]

非規範性說明

TCP端口88831883已向IANA註冊,分別用於MQTT TLS和非TLS通信。

諸如用戶數據報協議(UDP)之類的無連接網絡傳輸本身並不適合,因爲它們可能會丟失或重新排序數據。

4.3服務質量級別和協議流

MQTT根據此處定義的服務質量(QoS)級別交付應用程序消息。 傳遞協議是對稱的,在下面的描述中,客戶端和服務器可以分別充當發送者或接收者的角色。 傳遞協議僅與將應用程序消息從單個發件人傳遞到單個接收者有關。 當服務器將一個應用程序消息傳遞給多個客戶端時,每個客戶端將被獨立對待。 用於將應用程序消息發送到客戶端的QoS級別可能與入站應用程序消息的QoS級別不同。

以下各節中的非規範流程圖旨在顯示可能的實現方法。

4.3.1 QoS 0: At most once delivery

該消息是根據基礎網絡的功能傳遞的。 接收方不發送響應,發送方也不進行重試。 消息一次到達接收者或根本不到達。

在QoS 0傳遞協議中,發送方

  • 必須發送QoS = 0,DUP = 0 [MQTT-4.3.1-1]的PUBLISH數據包。

在QoS 0傳遞協議中,接收方

  • 在接收到PUBLISH數據包時,接受消息的所有權。

4.3.2 QoS 1: At least once delivery

這種服務質量確保了消息至少一次到達接收者。 QoS 1 PUBLISH數據包的變量頭中有一個數據包標識符,並由PUBACK數據包確認。 第2.3.1節提供了有關數據包標識符的更多信息。

在QoS 1傳遞協議中,發件方

  • 每次有新的應用消息要發佈時,必須分配一個未使用的包標識符。
  • 必須發送包含此數據包標識符的QoS數據包標識符,DUP = 0的PUBLISH數據包。
  • 必須將PUBLISH數據包視爲“未確認”,直到它已從接收方接收到相應的PUBACK數據包。 有關未確認消息的討論,請參見第4.4節。

一旦發件方收到PUBACK數據包,數據包標識符就可以重用。

請注意,在等待接收確認的同時,允許發件方發送帶有不同數據包標識符的其他PUBLISH數據包。

在QoS 1傳遞協議中,接收方

必須接受來自應用程序消息所有權的,來自輸入PUBLISH數據包的,包含數據包標識符的PUBACK數據包響應

發送PUBACK數據包後,接收者務必將包含相同數據包標識符的任何傳入PUBLISH數據包視爲新的發佈,而不論其DUP標誌的設置如何。

注1:在發送PUBACK之前,不需要接收者完成應用消息的傳遞。 當其原始發送方收到PUBACK數據包時,應用程序消息的所有權將轉移到接收方。 

4.3.3 QoS 2: Exactly once delivery

這是最高的服務質量,適用於既不能丟失消息也不能複製消息的情況。 與該服務質量相關的開銷增加了。

QoS 2消息的可變報頭中有一個數據包標識符。 第2.3.1節提供了有關數據包標識符的更多信息。 QoS 2 PUBLISH數據包的接收者通過兩步確認過程來確認接收。

在QoS 2傳遞協議中,發送者

  • 當有新的應用消息要發佈時,務必分配一個未使用的包標識符。
  • 必須發送包含此數據包標識符的QoS數據包,DUP = 0的PUBLISH數據包。
  • 必須將PUBLISH數據包視爲“未確認”,直到它已從接收方接收到相應的PUBREC數據包。 有關未確認消息的討論,請參見第4.4節。
  • 當它從接收器接收到一個PUBREC包時,必須發送一個PUBREL包。 該PUBREL包必須包含與原始PUBLISH包相同的包標識符。
  • 必須將PUBREL數據包視爲“未確認”,直到它已從接收器接收到相應的PUBCOMP數據包爲止。
  • 一旦發送了相應的PUBREL數據包,絕不能重新發送PUBLISH。

一旦發件者已收到PUBCOMP數據包,數據包標識符即可重新使用。

請注意,在等待接收確認的同時,允許發件人發送帶有不同數據包標識符的其他PUBLISH數據包。

在QoS 2傳遞協議中,接收方

  •   必須應答一個PUBREC響應,其中包含來自傳入PUBLISH數據包的數據包標識符,並已接受了應用消息的所有權。
  •   在接收到對應的PUBREL數據包之前,接收者務必通過發送PUBREC確認具有相同數據包標識符的任何後續PUBLISH數據包。 在這種情況下,它一定不能使重複的信息傳遞給任何轉發的收件人。
  •   必須通過發送包含與PUBREL相同的分組標識符的PUBCOMP分組來響應PUBREL分組。
  •   發送PUBCOMP後,接收者務必將包含該包標識符的任何後續PUBLISH包視爲新的發佈。

注1:在發送PUBREC或PUBCOMP之前,不需要接收者完成應用消息的傳遞。 當其原始發送方收到PUBREC數據包時,應用程序消息的所有權將轉移到接收方。

圖4.3顯示了有兩種方法可以使接收方處理QoS 2。 它們在流程中使消息可用於繼續傳遞的點有所不同。 方法A或方法B的選擇是特定於實現的。 只要實施方案正好選擇這些方法之一,這就不會影響QoS 2流的保證。 

4.4 Message delivery retry(消息重傳)

當客戶端在CleanSession設置爲0的情況下重新連接時,客戶端和服務器都必須使用其原始數據包標識符[MQTT-4.4.0-1]重新發送任何未確認的PUBLISH數據包(其中QoS> 0)和PUBREL數據包。 這是唯一需要重新發送信息的客戶端或服務器的情況。

4.5 Message receipt(消息回執)

當服務器獲得傳入應用程序消息的所有權時,它必須將其添加到具有匹配訂閱的那些客戶端的會話狀態中。 匹配規則在第4.7節[MQTT-4.5.0-1]中定義。

通常情況下,客戶會收到響應其創建的訂閱的消息。 客戶端還可能收到與任何其明確訂閱都不匹配的消息。 如果服務器自動爲客戶端分配了訂閱,則會發生這種情況。 客戶端還可以在進行UNSUBSCRIBE操作時接收消息。 客戶端必須根據適用的QoS規則確認收到的任何發佈數據包,無論其是否選擇處理包含[MQTT-4.5.0-2]的應用消息。

4.6 Message ordering(消息排序)

在實現本章其他地方定義的協議流時,客戶端必須遵循以下規則:

  •      當它重新發送任何PUBLISH數據包時,必須按發送原始PUBLISH數據包的順序重新發送它們(這適用於QoS 1和QoS 2消息)[MQTT-4.6.0-1]
  •      它必須按照接收到相應的PUBLISH數據包(QoS 1消息)的順序發送PUBACK數據包[MQTT-4.6.0-2]
  •      它必須按照接收到相應的PUBLISH數據包的順序(QoS 2消息)發送PUBREC數據包[MQTT-4.6.0-3]
  •      它必須按照接收到相應的PUBREC數據包的順序(QoS 2消息)發送PUBREL數據包[MQTT-4.6.0-4]

默認情況下,服務器務必將每個主題視爲“有序主題”。 它可以提供一種管理或其他機制,以允許將一個或多個主題視爲“無序主題” [MQTT-4.6.0-5]。

當服務器處理已發佈到有序主題的消息時,向每個訂閱者傳遞消息時,它必須遵循上面列出的規則。 另外,它必須按從任何給定客戶端[MQTT-4.6.0-6]收到的順序,向用戶(對於相同的主題和QoS)發送發佈數據包。

注:

上面列出的規則可確保在使用QoS 1發佈和訂閱消息流時,訂戶接收的每個消息的最終副本都將按照其最初發布的順序進行,但是可能會導致消息重複重新發送在其後繼消息之一之後收到的先前消息。例如,發佈者可能以1,2,3,4的順序發送消息,而訂閱者可能以1,2,3,2,3,4的順序接收消息。

如果客戶端和服務器在任何一次都確保不超過一條消息在運行中(通過在確認其前任之前不發送消息),那麼以後的任何一條消息都不會收到QoS 1消息-例如,訂戶可能會按1,2,3,3,4的順序接收它們,但不能按1,2,3,2,3,4的順序接收它們。將運行中窗口設置爲1還意味着即使發佈者針對同一主題發送具有不同QoS級別的消息序列,也將保留順序。

4.7 Topic Names and Topic Filters(主題名稱和主題過濾器)

4.7.1 Topic wildcards(主題通配符)

主題級別分隔符用於將結構引入主題名稱。 如果存在,它將主題名稱分爲多個“主題級別”。

訂閱的主題過濾器可以包含特殊的通配符,使您可以一次訂閱多個主題。

可以在主題過濾器中使用通配符,但不得在主題名稱[MQTT-4.7.1-1]中使用通配符。

4.7.1.1 Topic level separator(主題級別分隔符

正斜槓('/'U + 002F)用於分隔主題樹中的每個級別,併爲主題名稱提供層次結構。 當訂閱客戶端指定的主題過濾器中遇到兩個通配符中的任意一個時,主題級別分隔符的使用就很重要。 主題級別分隔符可以出現在“主題過濾器”或“主題名稱”中的任何位置。 相鄰主題級別分隔符表示長度爲零的主題級別。

4.7.1.2 Multi-level wildcard(多層通配符)

數字符號('#'U + 0023)是通配符,與主題中任意數量的級別相匹配。 多層通配符表示父級和任意數量的子級。 多級通配符必須單獨或在主題級分隔符之後指定。 無論哪種情況,它都必須是主題過濾器[MQTT-4.7.1-2]中指定的最後一個字符。

例如,如果客戶訂閱“ sport / tennis / player1 /#”,它將接收使用以下主題名稱發佈的消息:

· “sport/tennis/player1”

· “sport/tennis/player1/ranking”

· “sport/tennis/player1/score/wimbledon”

 

· “sport/#” also matches the singular “sport”, since # includes the parent level.

· “#” is valid and will receive every Application Message

· “sport/tennis/#” is valid

· “sport/tennis#” is not valid

· “sport/tennis/#/ranking” is not valid

4.7.1.3 Single level wildcard(單級通配符)

加號('+'U + 002B)是僅與一個主題級別匹配的通配符。

單級通配符可以在主題過濾器的任何級別(包括第一級和最後一級)中使用。 在使用的地方,它必須佔據整個過濾器[MQTT-4.7.1-3]的級別。 它可以在“主題過濾器”中的多個級別上使用,並且可以與多級通配符一起使用。

非規範性說明

For example, “sport/tennis/+” matches “sport/tennis/player1” and “sport/tennis/player2”, but not “sport/tennis/player1/ranking”. Also, because the single-level wildcard matches only a single level, “sport/+” does not match “sport” but it does match “sport/”.

非規範性說明

·         “+” is valid
·         “+/tennis/#” is valid
·         “sport+” is not valid
·         “sport/+/player1” is valid                                                                                                                                           
·         “/finance” matches “+/+” and “/+”, but not “+”

4.7.2  Topics beginning with $(以$開頭的主題)

服務器不能匹配主題過濾器開始使用通配符(#或+)與主題名稱以$字符[MQTT-4.7.2-1]開始。 服務器應防止客戶端使用此類主題名稱與其他客戶端交換消息。 服務器實現可以使用以前導$字符開頭的主題名稱,以用於其他目的。

非規範性說明

  • $SYS/ 已被廣泛用作包含服務器特定信息或控制API的主題的前綴
  • 應用程序不能出於自己的目的使用帶有前導$字符的主題

非規範性說明

  •        A subscription to “#” will not receive any messages published to a topic beginning with a $
  •        A subscription to “+/monitor/Clients” will not receive any messages published to “$SYS/monitor/Clients”
  •        A subscription to “$SYS/#” will receive messages published to topics beginning with “$SYS/”
  •        A subscription to “$SYS/monitor/+” will receive messages published to “$SYS/monitor/Clients”
  •        For a Client to receive messages from topics that begin with $SYS/ and from topics that don’t begin with a $, it has to subscribe to both “#” and “$SYS/#”

4.7.3 Topic semantic and usage(主題的語法和用法)

以下規則適用於主題名稱和主題過濾器:

  • 所有主題名稱和主題過濾器必須至少一個字符長[MQTT-4.7.3-1]
  • 主題名稱和主題過濾器區分大小寫
  • 主題名稱和主題過濾器可以包含空格字符
  • 開頭或結尾的“ /”會創建不同的主題名稱或主題過濾器
  • 僅包含“ /”字符的主題名稱或主題過濾器有效
  • 主題名稱和主題過濾器不得包含null字符(Unicode U + 0000)[Unicode] [MQTT-4.7.3-2]
  • 主題名稱和主題過濾器是UTF-8編碼的字符串,它們不得編碼爲超過65535字節[MQTT-4.7.3-3]。 參見第1.5.3節

主題名稱或主題過濾器中級別的數量外沒有其他限制,除了由UTF-8編碼的字符串的總長度。

當執行訂閱匹配時,服務器絕不能對主題名稱或主題過濾器進行任何規範化,或者對無法識別的字符進行任何修改或替換[MQTT-4.7.3-4]。 主題過濾器中的每個非通配級別都必須與“主題名稱”字符中的相應級別匹配,以使字符成功匹配。

非規範性說明

UTF-8編碼規則意味着可以通過比較編碼的UTF-8字節或比較解碼的Unicode字符來執行主題過濾器和主題名稱的比較

非規範性說明

  •  “ACCOUNTS” and “Accounts” are two different topic names
  •  “Accounts payable” is a valid topic name
  •  “/finance” is different from “finance”

將應用程序消息發送到其主題過濾器與附加到應用程序消息的主題名稱匹配的每個客戶端訂閱。 主題資源可以由管理員在服務器中預定義,也可以在服務器接收到第一個訂閱或具有該主題名稱的應用程序消息時由服務器動態創建。 服務器還可以使用安全組件來有選擇地授權給定客戶端對主題資源的操作。

4.8 Handling errors(錯誤處理)

除非另有說明,否則,如果服務器或客戶端遇到協議違規,則它必須關閉其上收到導致協議違規的控制數據包的網絡連接[MQTT-4.8.0-1]。

客戶端或服務器實現可能會遇到瞬態錯誤(例如,內部緩衝區已滿),這會阻止成功處理MQTT數據包。

如果客戶端或服務器在處理入站控制包時遇到暫態錯誤,則必須關閉其接收該控制包[MQTT-4.8.0-2]的網絡連接。 如果服務器檢測到暫時性錯誤,則不應斷開連接或對其與任何其他客戶端的交互產生任何其他影響。

5 安全

5.1 簡介

本章僅作爲指導,不具有規範性。 但是,強烈建議提供TLS [RFC5246]的服務器實現應使用TCP端口8883(IANA服務名稱:secure-mqtt)

解決方案提供商應考慮許多威脅。 例如:

  • 設備可能受到威脅
  • 客戶端和服務器中的靜態數據可能可以訪問
  • 協議行爲可能會有副作用(例如“定時攻擊”)
  • 拒絕服務(DoS)攻擊
  • 通訊可能被截取,更改,重新路由或披露
  • 欺騙控制包的注入

MQTT解決方案通常部署在不利的通信環境中。 在這種情況下,實現通常需要提供以下機制:

  •  用戶和設備的身份驗證
  •  授權訪問服務器資源
  •  MQTT控制包及其中包含的應用程序數據的完整性
  •  MQTT控制包及其中包含的應用程序數據的保密性

作爲一種傳輸協議,MQTT僅關注消息傳輸,並且實施者有責任提供適當的安全功能。 通常通過使用TLS [RFC5246]來實現。

除了技術安全問題外,還可能存在地域因素(例如,美國-歐盟SafeHarbor [USEUSAFEHARB]),行業特定的因素(例如PCI DSS [PCIDSS])和法規注意事項(例如Sarbanes-Oxley [SARBANES])。

5.2 MQTT解決方案:安全性和認證

一個實現可能希望符合特定的行業安全標準,例如NIST網絡安全框架[NISTCSF],PCI-DSS [PCIDSS],FIPS-140-2 [FIPS1402]和NSA Suite B [NSAB]。

有關在NIST網絡安全框架[NISTCSF]中使用MQTT的指南,請參見MQTT補充出版物《 MQTT》和《用於改善關鍵基礎設施網絡安全的NIST框架》 [MQTT NIST]。 使用行業認可,獨立驗證和認證的技術將有助於滿足合規性要求。

5.3 輕量級加密和受約束的設備

先進的加密標準[AES]和數據加密標準[DES]被廣泛採用。

ISO 29192 [ISO29192]爲加密原語提出了建議,這些密碼原語經過特殊調整可在受限的“低端”設備上執行。

5.4實施說明

在實現或使用MQTT時,要考慮許多安全問題。 以下部分不應視爲“檢查表”。

一個實現可能想要實現以下一些或全部功能:

5.4.1 服務器對客戶端的身份驗證

5.4.2 服務器對客戶端的授權

5.4.3 客戶端對服務器的身份驗證

5.4.4 應用消息和控制包的完整性

5.4.5 應用消息和控制包的私有性

5.4.6 不可拒絕的消息傳輸

5.4.7 檢測客戶端和服務器的危害

5.4.8 檢測異常行爲

5.4.9 其他安全考慮

5.4.10 Use of SOCKS

客戶端的實現應注意,某些環境將需要使用SOCKSv5 [RFC1928]代理進行出站網絡連接。 一些MQTT實現可以通過使用SOCKS來使用備用安全隧道(例如SSH)。 在實現選擇使用SOCKS的地方,它們應同時支持匿名和用戶名密碼身份驗證SOCKS代理。 在後一種情況下,實現應意識到SOCKS身份驗證可能以純文本形式進行,因此應避免使用相同的憑據連接到MQTT Server。

5.4.11安全配置文件

實現者和解決方案設計者可能希望將安全性視爲可以應用於MQTT協議的一組配置文件。 下面提供了分層安全性層次結構的示例。

5.4.11.1 Clear communication profile(清除通信配置文件)

5.4.11.2 Secured network communication profile

5.4.11.3 Secured transport profile

5.4.11.4 Industry specific security profiles

6   Using WebSocket as a network transport

如果MQTT通過WebSocket [RFC6455]連接進行傳輸,則適用以下條件:

  • ·MQTT控制包必須在WebSocket二進制數據幀中發送。 如果收到任何其他類型的數據幀,則接收者必須關閉網絡連接[MQTT-6.0.0-1]。
  • ·一個WebSocket數據幀可以包含多個或部分MQTT控制包。 接收者不得假定MQTT控制數據包在WebSocket幀邊界[MQTT-6.0.0-2]上對齊。
  • ·客戶端必須在其提供的[MQTT-6.0.0-3]的WebSocket子協議列表中包含“ mqtt”。
  • ·服務器選擇並返回的WebSocket子協議名稱必須爲“ mqtt” [MQTT-6.0.0-4]。
  • ·用於連接客戶端和服務器的WebSocket URI對MQTT協議沒有影響。

6.1 IANA注意事項

該規範要求IANA使用以下數據在“ WebSocket子協議名稱”註冊表下注冊WebSocket MQTT子協議:

7 一致性

MQTT規範定義了MQTT Client實現和MQTT Server實現的一致性。

MQTT實現可以同時作爲MQTT客戶端和MQTT服務器實現。 既接受入站連接又建立與其他服務器的出站連接的服務器必須同時作爲MQTT客戶端和MQTT服務器[MQTT-7.0.0-1]。

爲了與任何其他一致的實現[MQTT-7.0.0-2]互操作,一致的實現必須不要求使用本規範之外定義的任何擴展。

7.1一致性指標

7.1.1 MQTT服務器

MQTT服務器只有滿足以下所有條件,才符合此規範:

  1. 服務器發送的所有控制包的格式與第2章和第3章中描述的格式匹配。
  2. 它遵循第4.7節中描述的主題匹配規則。
  3. 它滿足以下各章中確定的所有MUST級別要求,但僅適用於客戶的要求除外:

-第1章-簡介

-第2章-MQTT控制數據包格式

-第3章-MQTT控制數據包

-第4章-操作行爲

-第6章-(如果MQTT通過WebSocket連接傳輸)

-第7章-一致性指標

一致性服務器必須支持使用一種或多種基礎傳輸協議,這些協議提供從客戶端到服務器以及從服務器到客戶端的有序無損字節流[MQTT-7.1.1-1]。 但是,一致性並不取決於它是否支持任何特定的傳輸協議。 服務器可以支持第4.2節中列出的任何傳輸協議,或者滿足[MQTT-7.1.1-1]要求的任何其他傳輸協議。

7.1.2 MQTT客戶端

MQTT客戶端只有滿足以下所有條件,才符合此規範:

  1. 客戶端發送的所有控制包的格式與第2章和第3章中描述的格式匹配。
  2. 它滿足以下各章中確定的所有“必須”級別的要求,但僅適用於服務器的要求除外:

-第1章-簡介

-第2章-MQTT控制數據包格式

-第3章-MQTT控制數據包

-第4章-操作行爲

-第6章-(如果MQTT通過WebSocket連接傳輸)

-第7章-一致性指標

合格的客戶端必須支持使用一種或多種基礎傳輸協議,這些協議提供從客戶端到服務器以及從服務器到客戶端的有序無損字節流[MQTT-7.1.2-1]。 但是,一致性並不取決於它是否支持任何特定的傳輸協議。 客戶端可以支持第4.2節中列出的任何傳輸協議,或者滿足[MQTT-7.1.2-1]要求的任何其他傳輸協議。

8.  Wirshark 抓包截圖

理解協議,最好的方法就是結合已知的工具,解析查看協議各類型幀的收發數據,並比對協議規範。這裏簡單的抓取了基本的協議幀。

這裏以 百度雲天工物接入 作爲 服務端,以MQTT FX(http://mqttfx.jensd.de/index.php)模擬客戶端,來抓取部分協議幀,百度雲天工物接入平臺,作爲成熟的IOT HUB 接入平臺,支持已經相當完善,實際使用也可以滿足。

MQTT FX 使用比較簡單,使用方法官方有說明,也可以在百度/阿里等IOT接入幫助文檔中看到相關使用說明,在此不做贅述。

MQTT FX 配置:

 

連接成功後,說明設備到雲端是通的,可以開始數據包的抓取了。

CONNECT:

 CONNECT ACK:

PING Request:

PING Response:

Subscribe Request:

Subscribe Ack:

Publish Message:

 

Unsubscribe Request:

 Unsubscribe Ack:

 Publish Message( QoS 1):

 Publish Ack :

注:5.0 的協議暫時還沒有看

V3.1.1 協議官方鏈接:http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/

V5.0   協議官方鏈接:http://docs.oasis-open.org/mqtt/mqtt/v5.0/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章