MQTT入門介紹(一)
一.MQTT簡述服務器
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸協議),是一種基於發佈/訂閱(publish/subscribe)模式的"輕量級"通信協議,該協議構建於TCP/IP協議上,由IBM在1999年發佈。MQTT最大優勢在於,能夠以極少的代碼和有限的帶寬,爲鏈接遠程設備提供實時可靠的消息服務。做爲一種低開銷、低帶寬佔用的即時通信協議,使其在物聯網、小型設備、移動應用等方面有較普遍的應用。網絡
MQTT是一個基於客戶端-服務器的消息發佈/訂閱傳輸協議。MQTT協議是輕量、簡單、開放和易於實現的,這些特色使它適用範圍很是普遍。在不少狀況下,包括受限的環境中,如:機器與機器(M2M)通訊和物聯網(IoT)。其在,經過衛星鏈路通訊傳感器、偶爾撥號的醫療設備、智能家居、及一些小型化設備中已普遍使用。運維
二.設計規範ui
因爲物聯網的環境是很是特別的,因此MQTT遵循如下設計原則:編碼
(1)精簡,不添加無關緊要的功能;spa
(2)發佈/訂閱(Pub/Sub)模式,方便消息在傳感器之間傳遞;設計
(3)容許用戶動態建立主題,零運維成本;隊列
(4)把傳輸量降到最低以提升傳輸效率;ip
(5)把低帶寬、高延遲、不穩定的網絡等因素考慮在內;ci
(6)支持連續的會話控制;
(7)理解客戶端計算能力可能很低;
(8)提供服務質量管理;
(9)假設數據不可知,不強求傳輸數據的類型與格式,保持靈活性。
三.主要特性
MQTT協議工做在低帶寬、不可靠的網絡的遠程傳感器和控制設備通信而設計的協議,它具備如下主要的幾項特性:
(1)使用發佈/訂閱消息模式,提供一對多的消息發佈,解除應用程序耦合。
這一點很相似於XMPP,可是MQTT的信息冗餘遠小於XMPP,,由於XMPP使用XML格式文原本傳遞數據。
(2)對負載內容屏蔽的消息傳輸。
(3)使用TCP/IP提供網絡鏈接。
主流的MQTT是基於TCP鏈接進行數據推送的,可是一樣有基於UDP的版本,叫作MQTT-SN。這兩種版本因爲基於不一樣的鏈接方式,優缺點天然也就各有不一樣了。
(4)有三種消息發佈服務質量:
Qos = 0; "至多一次",消息發佈徹底依賴底層TCP/IP網絡。會發生消息丟失或重複。這一級別可用於以下狀況,環境傳感器數據,丟失一次讀記錄無所謂,由於不久後還會有第二次發送。這一種方式主要普通APP的推送,假若你的智能設備在消息推送時未聯網,推送過去沒收到,再次聯網也就收不到了。
Qos = 1; "至少一次",確保消息到達,但消息重複可能會發生。
Qos = 0; "只有一次",確保消息到達一次。在一些要求比較嚴格的計費系統中,可使用此級別。在計費系統中,消息重複或丟失會致使不正確的結果。這種最高質量的消息發佈服務還能夠用於即時通信類的APP的推送,確保用戶收到且只會收到一次。
(5)小型傳輸,開銷很小(固定長度的頭部是2字節),協議交換最小化,以下降網絡流量。
這就是爲何在介紹裏說它很是適合"在物聯網領域,傳感器與服務器的通訊,信息的收集",要知道嵌入式設備的運算能力和帶寬都相對薄弱,使用這種協議來傳遞消息再適合不過了。
(6)使用Last Will和Testament特性通知有關各方客戶端異常中斷的機制。
Last Will:即遺言機制,用於通知同一主題下的其餘設備發送遺言的設備已經斷開了鏈接。
Testament:遺囑機制,功能相似於Last Will。
四.相關術語
(1) 網絡鏈接(NetWork Connection)
MQTT使用的底層傳輸協議基礎設施。
1) 客戶端使用它鏈接服務端
2) 它提供有序的、可靠的、雙向字節流傳輸
(2) 客戶端(Client)
使用MQTT的程序或設備。客戶端老是經過網絡鏈接到服務端。它能夠:
1) 發佈應用消息給其餘相關的客戶端
2) 訂閱以請求接收相關的應用消息
3) 取消訂閱以移除接受應用消息的請求
4) 從服務端斷開鏈接
(3) 服務端(Server)
一個程序或者設備、做爲發送消息的客戶端和請求訂閱的客戶端端之間的中介。服務端:
1) 接受來自客戶端的網絡鏈接
2) 接受客戶端發佈的應用消息
3) 處理客戶端的訂閱和取消訂閱請求
4) 轉發應用消息給符合條件的已訂閱客戶端
(4) 訂閱(Subscription)
訂閱包含一個主題過濾器(Topic Filter)和一個最大的服務質量(QoS)等級。訂閱與單個會話(Session)關聯。會話能夠包含對於一個的訂閱。會話的每一個訂閱都有一個不一樣的主題過濾器。
(5) 主題名(Topic Name)
附加在應用消息上的一個標籤,服務端已知且與訂閱匹配。服務端發送應用消息的一個副本給每個匹配的客戶端訂閱。
(6) 主題過濾器(Topic Filter)
訂閱中包含的一個表達式,用於表示相關的一個或多個主題。主題過濾器可使用通配符
(7) 會話(Session)
客戶端和服務端之間的狀態交互。一些會話持續時間長和網絡鏈接同樣,另外一些能夠在客戶端和服務端的多個連續網絡鏈接間擴展。
(8) 控制報文(MQTT Control Packet)
經過網絡鏈接發送的信息數據包。MQTT規範定義了十四種不一樣類型的控制報文,其中一個(PUBLISH報文)用於傳輸應用消息。
五.MQTT 控制報文
MQTT協議經過交換預約義的MQTT控制報文來通訊。MQTT控制報文由三部分組成,分別是:固定報頭(全部報文都包含)、可變報頭(部分報文包含)、有效載荷(部分報文包含)
Fixed header |
固定報頭 |
Variable header |
可變報頭 |
Payload |
有效載荷 |
(1)固定報頭 Fixed header
每一個MQTT控制報文都包含一個固定報頭,固定報頭的格式以下:
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
byte 1 |
MQTT控制報文的類型 |
用於指定報文類型的標誌位 |
||||||
Byte 2 ... |
剩餘長度 |
MQTT 控制報文的類型(固定報頭第一個字節,二進制7-4):
名字 |
值 |
報文流動方向 |
描述 |
Reserved |
0 |
禁止 |
保留 |
CONNECT |
1 |
客戶端到服務端 |
鏈接服務端 |
CONNACK |
2 |
服務端到客戶端 |
確認鏈接請求 |
PUBLISH |
3 |
兩個方向都容許 |
發佈消息 |
PUBACK |
4 |
兩個方向都容許 |
發佈確認 |
PUBREC |
5 |
兩個方向都容許 |
發佈收到(QoS2,第一步) |
PUBREL |
6 |
兩個方向都容許 |
發佈釋放(QoS2,第二步) |
PUBCOMP |
7 |
兩個方向都容許 |
發佈完成(QoS2,第三步) |
SUBSCRIBE |
8 |
客戶端到服務端 |
訂閱主題 |
SUBACK |
9 |
服務端到客戶端 |
訂閱確認 |
UNSUBSCRIBE |
10 |
客戶端到服務端 |
取消訂閱 |
UNSUBACK |
11 |
服務端到客戶端 |
取消訂閱確認 |
PINGREQ |
12 |
客戶端到服務端 |
心跳請求 |
PINGRESP |
13 |
服務端到客戶端 |
心跳響應 |
DISCONNECT |
14 |
客戶端到服務端 |
斷開鏈接 |
Reserved |
15 |
禁止 |
保留 |
報文標誌Flag(固定報頭,第一個字節3-0)
每種報文都對應了相關的標誌位,標誌位以下表所列,若是收到非法的標誌,接收者 必須關閉網絡鏈接。報文標誌列表以下:
控制報文 |
固定報頭標誌 |
Bit 3 |
Bit 2 |
Bit 1 |
Bit 0 |
CONNECT |
Reserved |
0 |
0 |
0 |
0 |
CONNACK |
Reserved |
0 |
0 |
0 |
0 |
PUBLISH |
Userd 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 |
DUP1 = 控制報文的重複分發標誌
QoS2 = PUBLISH報文的服務質量等級
RETAIN3 = PUBLISH報文的保留標誌
剩餘長度(固定報頭,第二個字節開始,最大4個字節):
剩餘長度(Remaining Length)表示當前報文剩餘部分的字節數,包含可變報頭和負載的數據。剩餘長度不包括用於編碼剩餘長度字段自己的字節數。
剩餘長度字段使用一個變長度編碼方案,對於小於128的值它使用單字節編碼。更大的值下面的方式處理。低7位有效位用於編碼數據,最高有效位用於指示是否有更多的字節,且按照大端方式進行編碼。所以每一個字節能夠編碼128個數值和一個延續位。剩餘長度字節最大4個字節。
字節數 |
最小值 |
最大值 |
1 |
0(0x00) |
127(0x7F) |
2 |
128(0x80,0x01) |
16383(0xFF,0x7F) |
3 |
16384(0x80,0x80,0x01) |
2097151(0xFF,0xFF,0x7F) |
4 |
2097152(0x80,0x80,0x80,0x01) |
268435455(0xFF,0xFF,0xFF,0x7F) |
(2)可變報頭 Variable header
某些MQTT控制報文包含一個可變頭部分。它在固定報頭和負載之間。可變報頭的內容根據報文類型的不一樣而不一樣,可變報頭的報文標識符字段存在於多個類型的報文裏。
報文標識符結構以下:
Bit |
7-0 |
byte 1 |
報文標識符MSB(字符串長度的最高有效字節) |
byte 2 |
報文標識符LSB(字符串長度的最低有效字節) |
以下列舉了那些MQTT控制報文須要報文標識符
控制報文 |
報文標識符字段 |
CONNECT |
不須要 |
CONNACK |
不須要 |
PUBLISH |
須要(若是QoS > 0) |
PUBACK |
須要 |
PUBREC |
須要 |
PUBREL |
須要 |
PUBCOMP |
須要 |
SUBSCRIBE |
須要 |
SUBACK |
須要 |
UNSUBSCRIBE |
須要 |
UNSUBACK |
須要 |
PINGREQ |
不須要 |
PINGRESP |
不須要 |
DISCONNECT |
不須要 |
(3)有效載荷 Payload
某些MQTT控制報文在報文的最後部分包含一個有效載荷,以下是包含有效載荷的控制報文列表:
控制報文 |
報文標識符字段 |
CONNECT |
須要 |
CONNACK |
不須要 |
PUBLISH |
可選 |
PUBACK |
不須要 |
PUBREC |
不須要 |
PUBREL |
不須要 |
PUBCOMP |
不須要 |
SUBSCRIBE |
須要 |
SUBACK |
須要 |
UNSUBSCRIBE |
須要 |
UNSUBACK |
不須要 |
PINGREQ |
不須要 |
PINGRESP |
不須要 |
DISCONNECT |
不須要 |