初出茅廬的小李第28篇博客之MQTT學習筆記

物聯網學習入門篇之MQTT協議

MQTT: Massage Queuing Telemetry Transport,消息隊列遙測傳輸
MQTT是基於互聯網的基礎協議TCP/IP協議而構建的,由IBM在1999年發佈,基於發佈和訂閱兩種模式(publish/subscribe)算是一種輕量級通訊協議,在2014年成爲了OASIS開放標準,很多語言都支持該協議。
MQTT特點:
發佈訂閱模式,一對多消息發佈
開放消息協議,簡單容易實現
有三種消息服務質量:
至多一次 會發生消息丟失或者重複 上報數據丟失一次影響不是很大
至少一次 確保消息到達但消息重複可能會發生。
只有一次 確保消息到達一次。即時通訊類或者計費類。

Last Will:遺言機制,用於通知同一主題下的其它設備發送遺言的設備已經斷開了連接。
Testament:遺囑機制。
三種身份:
Publish發佈者
Broker 代理者(服務器)
Subscribe訂閱者
發佈者和訂閱者都是客戶端,消息代理是服務器,消息發佈者可以同時是訂閱者

MQTT傳輸的消息分爲:主題(Topic)和負載(payload)

主題可以理解爲消息的類型,訂閱者訂閱(Subscribe)後,就會收到該主題(Topic)下的
消息內容既是負載(payload)。
負載(payload)可以理解爲消息的內容,是指訂閱者具體要使用的內容

MQTT會構建底層的網絡傳輸,它將建立客戶端到服務器的連接,提供兩者之前有序的,無
損的,基於字節流的雙向傳輸。當應用數據通過MQTT網絡發送時,MQTT會把與之相關
的服務質量(QoS)和主題名(Topic)相關聯。
MQTT的客戶端如何定義?
它是一個使用MQTT協議的應用程序或者設備,它總是建立到服務器的網絡連接。客戶端
可以:
(1) 發佈其它客戶端可能訂閱的消息主題。
(2) 訂閱其它客戶端發佈的消息主題
(3) 退訂或者刪除應用程序的消息
(4) 斷開與服務器的連接
MQTT的服務器如何定義?
MQTT的服務器被稱之爲“消息代理”也就是“Broker”這個詞的由來,它可以是一個應用程序或者一臺設備。它位於消息發佈者和訂閱者之間。
(1) 接受來自客戶端的網絡連接
(2) 接受客戶發佈的應用信息
(3) 處理來自客戶端的訂閱和退訂請求
(4) 向訂閱的客戶端轉發應用程序消息

訂閱:
訂閱包含主題篩選器(Topic Filter)和最大服務質量(QoS)。訂閱會與一個會話(Session)關聯。一個會話中每個訂閱都有一個不同的主題篩選器。
會話(Session)每個客戶端與服務器建立連接後就是一個會話,客戶端和服務器之間有狀態交互,會話存在於一個網絡之間,也可能在客戶端和服務端之間跨越多個連續的網絡連接。
主題名字(Topic Name)
連接到一個應用程序消息的標籤,該標籤與服務器的訂閱相匹配。服務器會將消息發送給訂閱所匹配標籤的每個客戶端。
主題篩選器(Topic Filter)
一個對主題名通配符的篩選器,在訂閱表達式中使用,表示訂閱所匹配的多個主題。
負載(Payload)
消息訂閱者所具體接收的內容

MQTT協議中的方法:
也就是一些動作的名稱用來表示對資源的操作,這個資源可以代表預先存在的數據或動態生成的數據,這取決於服務器的實現。
(1) Connect 等待與服務器建立連接。
(2) Disconecet 等待MQTT客戶端完成所做的工作,並與服務器斷開TCP/IP會話。
(3) Subscribe 等待完成訂閱
(4) UnSubscribe 等待服務器取消客戶端的一個或多個topics訂閱
(5) Publish MQTT客戶端發送消息請求,發送完成後返回應用程序線程

MQTT數據包結構
固定包頭(Fixed header)
所有的MQTT數據包裏都要有,表示數據包類型及數據包的分組類標識。

可變頭 (Variable header)
不是都需要有,取決於數據包類型,數據包類型決定了可變頭是否存在以及存在的內容

消息體 (payload)
存在部分數據包,表示客戶收到的具體內容

在這裏插入圖片描述
在這裏插入圖片描述
4位數據包類型,不同類型具體標識也是4位
在這裏插入圖片描述
有16種情況,其中兩種不可用,還剩14種情況,有好幾個是成對的數據包類型
在這裏插入圖片描述
(1) DUP:發佈消息的副本。用來在保證消息的可靠傳輸,如果設置爲1,則在下面的變長中增加MessageId,並且需要回復確認,以保證消息傳輸完成,但不能用於檢測消息重複發送。
(2)QoS:發佈消息的服務質量,即:保證消息傳遞的次數
Ø00:最多一次,即:<=1
Ø01:至少一次,即:>=1
Ø10:一次,即:=1
Ø11:預留
(3)RETAIN: 發佈保留標識,表示服務器要保留這次推送的信息,如果有新的訂閱者出現,就把這消息推送給它,如果沒有那麼推送至當前訂閱者後釋放。
固定頭的第二字節用來保存變長頭部和消息體的總大小的,但不是直接保存的。這一字節是可以擴展,其保存機制,前7位用於保存長度,後一部用做標識。當最後一位爲1時,表示長度不足,需要使用二個字節繼續保存。
在這裏插入圖片描述
很多類型數據包中都包括一個2字節的數據包標識字段,這些類型的包有:PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。
Payload消息體位MQTT數據包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四種類型的消息:

(1)CONNECT,消息體內容主要是:客戶端的ClientID、訂閱的Topic、Message以及用戶名和密碼。
(2)SUBSCRIBE,消息體內容是一系列的要訂閱的主題以及QoS。
(3)SUBACK,消息體內容是服務器對於SUBSCRIBE所申請的主題及QoS進行確認和回覆。
(4)UNSUBSCRIBE,消息體內容是要取消訂閱的主題。
基本概念 Basic Conception
Session 會話
定義
• 定義:某個客戶端(由ClientID作爲標識)和某個服務器之間的邏輯層面的通信
• 生命週期(存在時間):會話 >= 網絡連接
ClientID
• 客戶端唯一標識,服務端用於關聯一個Session
• 只能包含這些 大寫字母,小寫字母 和 數字(0-9a-zA-Z),23個字符以內
• 如果 ClientID 在多次 TCP連接中保持一致,客戶端和服務器端會保留會話信息(Session)
• 同一時間內 Server 和同一個 ClientID 只能保持一個 TCP 連接,再次連接會踢掉前一個
CleanSession 標記
• 在Connect時,由客戶端設置
• 0 —— 開啓會話重用機制。網絡斷開重連後,恢復之前的Session信息。需要客戶端和服務器有相關Session持久化機制。
• 1 —— 關閉會話重用機制。每次Connect都是一個新Session,會話僅持續和網絡連接同樣長的時間。
客戶端 Session
• 已經發送給服務端,但是還沒有完成確認的 QoS 1 和 QoS 2 級別的消息
• 已從服務端接收,但是還沒有完成確認的 QoS 2 級別的消息
服務器端 Session
• 會話是否存在,即使會話狀態的其它部分都是空 (SessionFlag)
• 客戶端的訂閱信息 (ClientSubcription)
• 已經發送給客戶端,但是還沒有完成確認的 QoS 1 和 QoS 2 級別的消息
• 即將傳輸給客戶端的 QoS 1 和 QoS 2 級別的消息
• 已從客戶端接收,但是還沒有完成確認的 QoS 2 級別的消息
• (可選)準備發送給客戶端的 QoS 0 級別的消息
長連接維護與管理
Keep Alive 心跳
• 目的是保持長連接的可靠性,以及雙方對彼此是否在線的確認。
• 客戶端在Connect的時候設置 Keep Alive 時長。如果服務端在 1.5 * KeepAlive 時間內沒有收到客戶端的報文,它必須斷開客戶端的網絡連接
• Keep Alive 的值由具體應用指定,一般是幾分鐘。允許的最大值是 18 小時 12 分 15 秒
Will 遺囑
• 遺囑消息(Will Message)存儲在服務端,當網絡連接關閉時,服務端必鬚髮布這個遺囑消息,所以被形象地稱之爲遺囑,可用於通知異常斷線。
• 客戶端發送 DISCONNECT 關閉鏈接,遺囑失效並刪除
• 遺囑消息發佈的條件,包括:
• 服務端檢測到了一個 I/O 錯誤或者網絡故障
• 客戶端在保持連接(Keep Alive)的時間內未能通訊
• 客戶端沒有先發送 DISCONNECT 報文直接關閉了網絡連接
• 由於協議錯誤服務端關閉了網絡連接
• 相關設置項,需要在Connect時,由客戶端指定
• Will Flag —— 遺囑的總開關
• 0 – 關閉遺囑功能,Will QoS 和 Will Retain 必須爲 0
• 1 – 開啓遺囑功能,需要設置 Will Retain 和 Will QoS
• Will QoS —— 遺囑消息 QoS
• 可取值 0、1、2,含義與消息QoS相同
• Will Retain —— 遺囑是否保留
• 0 – 遺囑消息不保留,後面再訂閱不會收到消息
• 1 – 遺囑消息保留,持久存儲
• Will Topic —— 遺囑話題
• Will Payload —— 遺囑消息內容
消息基本概念
報文標識 Packet Identifier
• 存在報文的可變報頭部分,非零兩個字節整數 (0-65535]
• 一個流程中重複:這些報文包含 PacketID,而且在一次通信流程內保持一致:
• PUBLISH(QoS>0 時),PUBACK,PUBREC,PUBREL,PUBCOMP
• SUBSCRIBE, SUBACK
• UNSUBSCIBE,UNSUBACK
• 新的不重複:客戶端每次發送一個新的這些類型的報文時都必須分配一個當前 未使用的PacketID
• 當客戶端處理完這個報文對應的確認後,這個報文標識符就釋放可重用。
• 獨立維護:客戶端和服務端彼此獨立地分配報文標識符。因此,客戶端服務端組合使用相同的報文標識符可以實現 併發 的消息交換。可能出現一下情況,並不算異常:

Payload 有效載荷,消息體
• 最大允許 256MB
• Publish 的 Payload 允許爲空。在很多場合下,代表將持久消息(或者遺囑消息)清空。
• UTF-8編碼
Retain 持久消息(粘性消息)
• RETAIN 標記:每個Publish消息都需要指定的標記
• 0 —— 服務端不能存儲這個消息,也不能移除或替換任何 現存的保留消息
• 1 —— 服務端必須存儲這個應用消息和它的QoS等級,以便它可以被分發給未來的訂閱者
• 每個Topic只會保留最多一個 Retain 持久消息
• 客戶端訂閱帶有持久消息的Topic,會立即受到這條消息
• 服務器可以選擇丟棄持久消息,比如內存或者存儲喫緊的時候
• 如果客戶端想要刪除某個Topic 上面的持久消息,可以向這個Topic發送一個Payload爲空的持久消息
• 遺囑消息(Will)的Retain持久機制同理
QoS 服務等級(消息可靠性)

最多一次 At most Once(QoS == 0)

沒有回覆,不需要存儲。有可能丟失(網絡異常斷開,業務層繁忙或者錯誤)
至少一次 At least Once(QoS == 1 )
筆記參考了大神博客地址如下
https://blog.csdn.net/aa1215018028/article/details/84888096

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