MQTT 基本認知

weixin_33749242發表於2018-03-28

初始 MQTT

物聯網 (internet of thing) ,表示的是可以把一些帶某些感測器的裝置(終端),接入到網際網路的行為。
通過網際網路連線這些裝置,這些裝置就能夠互相協作。
MQTT就是這些裝置之間資料通訊的一個基於 TCP/IP 的協議。

2701794-fa8dc92348e8c68a.png
image.png

每個終端都和實現了 MQTT 協議的代理/伺服器相連。
通過 published MQTT 代理伺服器的某個主題 傳送資料。
通過 subscription 從 MQTT 代理伺服器獲取自己訂閱的 主題 資料。

代理伺服器本身不產生資料,資料全是由連結到這個代理伺服器的終端產生。
終端往伺服器傳送資料,在伺服器訂閱了主題的終端,接受另外一個終端傳送到伺服器,並通過伺服器轉發到自己。


為何選擇 MQTT 協議?

MQTT 協議是一種輕量級的、靈活的網路協議。並且非常適合 IOT 的場景。

  1. 首先 IOT 協議的定義非常小巧,不會像 HTTP、HTTPS 那麼重量級。
  2. 一般支援 IOT 的裝置的網路傳輸環境和自身的計算能力都比價薄弱。正好合適MQTT 對網路和資料要求不高的輕量級協議。

為什麼不選擇其他的網路協議?

大多數開發人員已經熟悉了 HTTP WEB 協議。那麼為什麼不讓 IOT 設定連結到 WEB 服務?
裝置可以採用 HTTP 請求的形式傳送資料,並採用 HTTP 響應的形式從伺服器獲取資料,接受更新。
因為對於 IOT 的裝置來說,這種主動請求--> 被動等待應答的 資料傳輸模型存在嚴重的侷限性:

  • HTTP 是一種同步協議。客戶端需要等待伺服器的響應。Web 瀏覽器具有這樣的要求,但它的代價是犧牲了可伸縮性。 在 IoT 領域,大量的裝置以及很可能不可靠或者高延遲的網路使得同步通訊成為問題。非同步訊息協議更適合 IoT 應用程式。感測器只負責傳送資料,讓網路確定將其傳送到目標裝置和伺服器的最佳路線和時間。

  • HTTP 是單向的。客戶端必須主動的發起請求。在 IoT 應用程式中,裝置或感測器通常是客戶端,就意味著,除非使用者或應用程式主動請求,否則無法接受來自伺服器的資料。

  • HTTP 是一個 1-1 的協議。客戶端發出請求,伺服器進行相應。它們是一對一的對應關係。但是需要把 HTTP 這種 1-1的關係,改程式 IOT 中很常見的 1 對多的關係,實現起來很困難,而且成本也很高。而 1 對多在 IoT 中很常見。

  • HTTP 相對於 MQTT 來說,是一個比較重的協議,它不適合IOT 終端裝置受限的網路和較差的計算能力。

那麼,MQTT 為什麼如此輕便且靈活?MQTT 協議的一個關鍵的特性是 釋出/訂閱模型。它將資料的釋出者和接受者分離。

一個裝置終端既可以是資料的釋出者(published) 也可以是資料的訂閱者(subscription)

一個裝置如果要釋出資料,只需要往代理伺服器中相應的主題釋出資料內容即可。
一個裝置如果需要接受到資料,只需要在代理伺服器中,提前訂閱自己需要關注的主題即可。


MQTT 的基本體驗

MQTT 最基本的體驗,就是使用 mosquitto
Mosquitto是一款實現了 MQTT v3.1 協議的開源訊息代理軟體,提供輕量級的,支援釋出/訂閱的的訊息推送模式,使裝置對裝置之間的短訊息通訊簡單易用。
它可以理解成一個 MQTT 的代理伺服器。

基本步驟如下:

  1. 首先使用 brew install
brew install mosquitto
2701794-c17b898b056f48e2.png
image.png

安裝成功截圖

2701794-4ecd189ffd4495ce.png
image.png

使用 brew services start mosquitto 啟動 MQTT 服務

執行截圖

2701794-5045e207301d9dc9.png
image.png

然後再開啟另外兩個終端視窗,模擬兩個IOT裝置。A 訂閱 MQTT 服務。B 向 MQTT 的服務傳送資料。

A訂閱當前MQTT的某個服務。

mosquitto_sub -t "dw/demo"
2701794-7dbeebf0ae200d15.png
image.png

B向 MQTT 伺服器釋出(published) 資料。

 mosquitto_pub -t "dw/demo" -m "hello MQTT"
2701794-9e8902952ef93748.png
image.png

然後,我們就可以在A控制檯裡看到由 B 通過 MQTT 服務傳送的資料了。

2701794-ecffef7373945a79.png
image.png

基本流程圖

2701794-ef0fe921faa085c0.png
image.png

控制檯 A 向 MQTT 伺服器訂閱 dw/demo 服務,並被動的等待 MQTT 伺服器返回資料。
控制檯 B 主動的向 MQTT 伺服器的 dw/demo 服務傳送 published 資料,之後。伺服器會主動向事先訂閱了 dw/demo 的終端分發此訊息。


瞭解 MQTT 協議

MQTT 是一種連結協議,它指定了如何組織資料位元組並通過 TCP/IP 網路傳輸它們。但實際上,開發人員並不需要連結這個連結協議的具體細節。我們只需要知道,每條訊息都有一個命令和資料有效負載。該命令定義訊息型別(比如 CONNECT 訊息或者 SUB SCRIBE 訊息)。所有的 MQTT 庫和工具都提供了直接處理這些訊息的基本方法,並且能自動填充一些必要的欄位(在資料包的對應位元組填充),比如訊息和客戶端 ID。

首先客戶端傳送一條CONNECT訊息來連結代理。CONNECT 訊息要求建立從客戶端到代理伺服器的連結。

CONNECT 命令的基本引數

  • cleanSession : 此標誌指定是否是持久連結。持久會話會將所有的訂閱和可能丟失的訊息(具體取決於 QoS)都儲存在代理(伺服器)中。
  • username : 連結代理伺服器的使用者名稱。(對,代理伺服器不是誰想連,想連就能連)
  • password : 連結代理伺服器的密碼。(對,代理伺服器不是誰想連,想連就能連)
  • lasWillTopic: 連結意外中斷,代理伺服器會像某個主題傳送一條 last will 訊息。
  • lastWillQos : last will 訊息的 QoS。
  • lastWillMessage : last will 訊息本身。
  • KeepAlive : 這是客戶端通過 ping 伺服器來保持連結有效所需的時間間隔。

當客戶端向代理伺服器傳送一條 CONNECT 命令之後,伺服器會呼叫 CONNACK命令,告知服務連結的狀態。

CONNACK 命令的基本引數

  • sessionPresent : 此參數列明連結是否已有一個持久會話。也就是說,連線了訂閱的主題,而且會接受丟失的訊息???
  • returnCode : 0 表示成功。otherwise 失敗。

當客戶端和伺服器建立連線之後,客戶端就可以向伺服器訂閱某些主題的。(傳送一條或多條 SUBSCRIBE訊息)。
表明當伺服器接受到其他終端推送的此主題資料時,伺服器會預設傳送給它。

SUBSCRIBE 引數列表

  • QoS : 服務質量 (quality of services)。一般有3個列舉值。
    • 0 : 表示不可靠服務,訊息僅推送一次,如果當前客戶端線上,或者因為網路原因,沒有收到就沒有收到。
    • 1 : 訊息至少傳遞 1 次。一次不成功,傳遞第二次,第 N 次。可能會出現重複資料的情況。
    • 2 : 訊息恰好傳遞 1 次。雙方通過 4 次握手,保證訊息能準確的從伺服器傳遞給客戶端,而且只傳一次。
      d

QoS 引數雖然在客戶端指定,但規定的是伺服器傳遞資料的模式。所以,QOS 是用來約束伺服器,而不是客戶端本身。

  • topic : 客戶端要訂閱的主題。

一個主題可以有多個級別,級別之間用斜槓字元分隔。例如 , "dw/demo""/ibm/bluemix/qmqt" 都是有效主題。


當客戶端成功的向伺服器訂閱某個主題之後,伺服器會返回一條 SUBACK 的訊息,其中包含一個或者多個 returnCode 引數。

SUBACK訊息引數

returnCode : 值 0 - 2 ,表示成功訂閱,並返回這個訂閱訊息的 QOS。值 128 : 訂閱失敗。


既然客戶端可以向伺服器訂閱某個主題,當然也可以取消訂閱。
SUBSCRIBE訂閱命令相反的命令是UNSUBSCRIBE取消訂閱命令。
此命令非常簡單。只有一個topic(主題)引數。

  • topic : 此引數就是客戶端取消訂閱的主題。

上面講的是訂閱,訂閱是需要有訊息從伺服器傳送過來的。但是伺服器本身基本不產生資料,那資料從何而來呢?
通過另外一個客戶端執行PUBLISH命令,往代理伺服器傳送資料。並最終通過代理伺服器將資料傳遞給訂閱了此服務的客戶端。

PUBLISH 訊息引數

  • topicName : 釋出訊息的相關主題。
  • qos : 訊息傳遞的質量水平。(約束伺服器)
  • retainFlag : 此標誌表明伺服器是否保留該訊息作為針對此主題的最後一條已知訊息。
  • payload : 訊息中的實際資料。它可以是文字字串或者二進位制大物件資料(圖片)

對於 MQTT 的一張基本理解圖

2701794-11965e9e0d64dc99.png
image.png

基本流程圖:

2701794-d907bee8133254dd.png
image.png

最後總結

  1. MQTT 是一個輕量級,用於計算能力弱,網路環境差的終端裝置之間的資料傳輸。
  2. MQQ 是基於一個 釋出/訂閱 的基本模式。
  3. 每個終端都可以從伺服器訂閱某些主題,也可以往代理伺服器釋出某些主題。
  4. 當伺服器接受到了某些終端傳送過來的資料之後,會向訂閱了這個服務的終端推送這些資料。

參考資料:初識 MQTT