MQTT通訊協議介紹
一:MQTT協議介紹
MQTT(Message Queuing Telemetry Transport,訊息佇列遙測傳輸)是IBM開發的一個即時通訊協議,它是一種輕量級的、基於代理的“釋出/訂閱”模式的訊息傳輸協議。其具有協議簡潔、小巧、可擴充套件性強、省流量、等優點。可在不可靠的網路環境中進行擴充套件,適用於裝置硬體儲存空間或網路頻寬有限的場景。使用MQTT協議,訊息傳送者與接收者不受時間和空間的限制。物聯網平臺支援裝置使用MQTT協議接入。
二:MQTT協議的主要特點
1、使用釋出/訂閱訊息模式,提供一對多的訊息釋出,解除應用程式耦合
2、使用 TCP/IP 提供網路連線
3、有三種級別的訊息釋出服務質量QoS(Quality of Service)
-
“至多一次”(Qos = 0),訊息釋出完全依賴底層 TCP/IP 網路。會發生訊息丟失或重複。這一級別可用於如下情況,環境感測器資料,丟失一次讀記錄無所謂,因為不久後還會有第二次傳送。
-
“至少一次”(Qos = 1),確保訊息到達,但訊息重複可能會發生。
-
“只有一次”(Qos = 2),確保訊息到達一次。訊息丟失和重複都是不可接受的,使用這個服務質量等級會有額外的開銷。
三:MQTT協議的核心角色
MQTT 協議主要有三大核心角色:釋出者(Publisher)、Broker代理伺服器(轉發者) 、訂閱者(Subscriber) 。其中訊息的釋出者和訂閱者都是客戶端(Client)角色,訊息代理是伺服器,訊息釋出者可以同時是訂閱者。 當Client釋出某個主題的訊息時,Broker會將該訊息分發給任何已訂閱該主題的Client。
MQTT伺服器
MQTT服務端通常是一臺伺服器。它是MQTT資訊傳輸的樞紐,負責將MQTT客戶端傳送來的資訊傳遞給MQTT客戶端。MQTT服務端還負責管理MQTT客戶端。確保客戶端之間的通訊順暢,保證MQTT訊息得以正確接收和準確投遞。
MQTT客戶端
MQTT客戶端可以向服務端釋出資訊,也可以從服務端收取資訊。我們把客戶端傳送資訊的行為成為“釋出”資訊。而客戶端要想從服務端收取資訊,則首先要向服務端“訂閱”資訊。“訂閱”資訊這一操作很像我們在微信中訂閱的公眾號,當公眾號更新時,微信會向訂閱了該公眾號的使用者傳送資訊,告訴他們有文章更新了。
MQTT主題
剛剛我們在講解MQTT客戶端訂閱資訊時,使用了使用者在微信中訂閱公眾號的這個例子。在MQTT通訊中,客戶端所訂閱的肯定不是一個個公眾號,而是一個個“主題”。MQTT服務端在管理MQTT資訊通訊時,就是使用“主題”來控制的。
四:連線MQTT服務端
MQTT客戶端要想通訊,必須經過MQTT服務端。因此MQTT客戶端無論是釋出訊息還是訂閱訊息,首先都要連線MQTT服務端。下面我們看一下MQTT客戶端連線服務端的詳細過程。
1、首先MQTT客戶端將會向服務端傳送連線請求。該請求實際上是一個包含有連線請求資訊的資料包。這個資料包的官方名稱為CONNECT 2、MQTT服務端收到客戶端連線請求後,會向客戶端傳送連線確認。同樣的,該確認也是一個數據包。這個資料包官方名稱為CONNACK。
以上就是MQTT客戶端在連線服務端的兩步操作。接下來,我們一起來了解一下客戶端在連線服務端時所傳送的CONNECT報文內容。
clientId – 客戶端ID
ClientId是MQTT客戶端的標識。MQTT服務端用該標識來識別客戶端。因此ClientId必須是獨立的。如果兩個MQTT客戶端使用相同ClientId標識,服務端會把它們當成同一個客戶端來處理。通常ClientId是由一串字元所構成的
username(使用者名稱)和password(密碼)
這裡的使用者名稱和密碼是用於客戶端連線服務端時進行認證需要的。有些MQTT服務端需要客戶端在連線時提供使用者名稱和密碼。只有客戶端正確提供了使用者名稱和密碼後,才能連線服務端。否則服務端將會拒絕客戶端連線,那麼客戶端也就無法釋出和訂閱訊息了。
username(使用者名稱)和password(密碼)是可選的CONNECT資訊。也就是說,有些服務端開啟了客戶端使用者密碼認證,這種服務端需要客戶端在連線時正確提供認證資訊才能連線。當然,那些沒有開啟使用者密碼認證的服務端無需客戶端提供使用者名稱和密碼認證資訊
cleanSession – 清除會話
要說明cleanSession的具體含義,首先要從MQTT網路環境講起。MQTT客戶端與服務端的連線可能不是非常穩定,在不穩定的網路環境下,要想保證所有資訊傳輸都能夠做到準確無誤,這是非常困難的。
為了保證重要的MQTT報文可以被客戶端準確無誤的收到。在服務端向客戶端傳送報文後,客戶端會向服務端返回一個確認報文。如果服務端沒有收到客戶端返回的確認報文,那麼服務端就會認為剛剛傳送給客戶端的報文沒有被準確無誤的送達。在這種情況下,服務端將會執行以下兩個操作:
1、將尚未被客戶端確認的報文儲存起來
2、再次嘗試向客戶端傳送報文,並且再次等待客戶端發來確認資訊。
如果 cleanSession 被設定為“true”。那麼服務端不需要客戶端確認收到報文,也不會儲存任何報文。在這種情況下,即使客戶端錯過了服務端發來的報文,也沒辦法讓服務端再次傳送報文。 反過來,如果我們將 cleanSession 設定為”false”。那麼服務端就知道,後續通訊中,客戶端可能會要求我儲存沒有收到的報文。
keepAlive – 心跳時間間隔
MQTT服務端執行過程中,當有客戶端因為某種原因斷開了與服務端的連線,服務端需要實時瞭解這一情況。KeepAlive正是用於服務端了解客戶端連線情況的。
客戶端在沒有向服務端傳送資訊時,可以定時向服務端傳送一條訊息。這條用於心跳機制的訊息也被稱作心跳請求。
心跳請求的作用正是用於告知服務端,當前客戶端依然線上。服務端在收到客戶端的心跳請求後,會回覆一條訊息。這條回覆訊息被稱作心跳響應。
客戶端在心跳間隔時間內,如果有訊息釋出,那就直接釋出訊息而不釋出心跳請求,但是在心跳間隔時間內,客戶端沒有訊息釋出,那麼它就會發布一條心跳請求給服務端,這個心跳請求的目的就是為了告訴服務端,我還線上。
五: SUBSCRIBE – 訂閱主題
當客戶端連線到服務端後,除了可以釋出訊息,也可以接收訊息。所有MQTT訊息都有主題。客戶端要想接收訊息,首先要訂閱該訊息的主題。這樣,當有客戶端向該主題釋出訊息後,訂閱了該主題的客戶端就能接收到訊息了。
客戶端要想訂閱主題,首先要向服務端傳送主題訂閱請求。客戶端是通過向服務端傳送SUBSCRIBE報文來實現這一請求的。客戶端在訂閱主題時也可以明確QoS。服務端會根據SUBSCRIBE中的QoS來提供相應的服務保證。