MQTT學習筆記

由於工做須要,瞭解了一下MQTT。順便記下來,如今還不會用。html

1、概述

MQTT(Message Queuing Telemetyr Transport  消息隊列遙測傳輸協議):基於發佈/訂閱(Publish/Subscribe)模式的輕量級通信協議,該協議構建於TCP/IP協議之上。數組

MQTT運行於TCP之上,屬於應用層協議。安全

 

2、MQTT消息格式

每條MQTT命令消息的消息頭都包含一個固定的報頭,有些消息會攜帶一個可變報文頭和一個負荷。消息格式以下:服務器

固定報文頭|可變報文頭|負荷微信

 

一、  固定報文頭(Fixed Header)

最少有兩個字節,第一個字節包含消息的類型(Message Type)和QoS級別等標誌位。第二個字節開始是剩餘長度字節,該長度是後面的可變報文頭加消息負載的總長度,該字段最多容許四個字節。網絡

剩餘長度字段單個字節的最大值爲0x7F. 也就是127個字節。MQTT協議規定,單個字節的最高位若是是1,表示後續還有字節存在,第八位起延續位的做用。異步

因爲MQTT協議最多使用四個字節表示剩餘長度,而且最後一個字節的最大值只能是0x7F,而不是0xFF。因此能發送的最大消息長度是256MB,而不是512MB。工具

 

 

二、  可變報文頭(Variable Header)

主要包含協議名,協議版本,鏈接標誌,心跳間隔時間,鏈接返回碼,主題名等。ui

 

三、  有效負荷

實際上能夠理解爲消息的主體。當MQTT發送的消息類型是CONNECT(鏈接)、PUBLISH(發佈)、SUBSCRIBE(訂閱)、SUBACK(訂閱確認)、UBSUNSCRIBE(取消訂閱)時會帶有負荷。編碼

 

3、MQTT的主要特性

一、MQTT的消息類型

固定報文頭中的第一個字節包含鏈接標誌,鏈接標誌用來區分MQTT的消息類型。MQTT協議擁有14中不一樣的消息類型。以下圖:

可簡單分爲鏈接及終止、發佈和訂閱、Qos2消息的機制以及各類確認ACK。

 

二、消息質量(QoS)

MQTT消息質量有三個等級,QoS 0、Qos 一、Qos 2。

Qos 0:最多分發一次,消息的傳遞徹底依賴底層的TCP/IP網絡,協議裏沒有定義應答和重試。消息只會到達服務端一次,要麼就沒到達。

Qos 1:至少分發一次、服務器的消息接收由PUBACK消息進行確認,若是通訊鏈路或設備異常,或指定時間內沒有收到確認消息,發送端會重發這條在消息頭中設置了Dup位的消息。

Qos 2:只分發一次。最高級別的消息傳遞,消息丟失和重複都是不可接受的,使用這個服務質量等級會有額外的開銷。

 

三、遺願標誌(Will Flag)

在可變報文頭的鏈接標誌位字段(Connect Flags)裏面有三個will標誌位:Will Flag  Will Qos和Retain Flag。這些will字段用於監控客戶端與服務器之間的鏈接情況。

遺願消息:服務器與客戶端通訊時,當遇到異常或客戶端心跳超時的狀況,MQTT服務器會替客戶端發佈一個will消息。固然若是服務器收到來自客戶端的DISCONNECT消息則不會觸發wiwll消息的發送。所以will字段能夠應用於設備掉線後通知用戶的場景

 

四、  鏈接保活心跳機制(keep Alive Timer)

MQTT客戶端能夠設置一個心跳間隔時間(keep Alive Timer),表示在每一個心跳檢測時間內發送一條消息。若是在這個時間週期內,沒有業務數據相關的消息,客戶端會發送一個PINGREQ消息,相應的,服務器會返回一個PINGRESP消息進行確認。

若是服務器在一個半(1.5)個心跳間隔時間週期內沒有收到來自客戶端的消息,就會斷開與客戶端的鏈接。心跳間隔時間最大值能夠設置爲18個小時,8表示客戶端不會斷開。

 

4、MQTT其餘特色

一、異步發佈/訂閱實現

發佈/訂閱模式解耦了發佈消息的客戶(發佈者)和訂閱消息的客戶(訂閱者)之間的關係。發佈者與訂閱者並不須要直接創建聯繫。

這個模式的好處有:

1)  發佈者與訂閱者只須要知道同一個消息代理便可。

2)  發佈者與訂閱者不須要直接交互,不須要同時在線。

 

二、二進制格式實現

MQTT基於二進制而不是字符串。固定報文頭僅有兩個字節,相比於其餘協議(HTTPS 和XMPP都是基於字符串實現,有冗長的頭部),發送一條消息更省流量

 

三、MQTT的安全

因爲MQTT運行於TCP層之上而且以明文傳輸,可使用Wireshark看到MQTT發送的全部消息,消息指令一覽無遺。這會帶來必定的風險:

1)  設備可能會被盜用

2)  客戶端和服務端的靜態數據多是可訪問的(可能會被修改)

3)  協議行爲可能有反作用(如計時器攻擊)

4)  拒絕服務攻擊

5)  通訊可能會被攔截 修改 重定向或者泄露

6)  虛假控制報文注入

 

做爲傳輸協議,MQTT只關注消息傳輸,提供安全功能是開發者的責任。

 

四、認證

支持兩種層次的認證

1)  應用層:MQTT支持客戶標識,用戶名和密碼認證

客戶標識:MQTT客戶端能夠發送最多65535個字符做爲客戶標識,通常來講可使用嵌入式芯片的MAC地址或芯片序列號。

用戶名和密碼:支持經過CONNECT消息的USERNAME和password字段發送用戶名和密碼。可是因爲是用的明文傳輸,抓包工具很容易就獲取。

 

2)  傳輸層:傳輸層可使用TLS,除了加密通信,還可使用X509證書來認證設備。

在傳輸層認證是這樣的:MQTT代理在TLS握手成功以後能夠繼續發送客戶端的X509證書來認證設備,若是設備不合法就中斷鏈接。

 

五、  選擇用戶數據格式

MQTT協議只實現了傳送消息的格式,並無限制用戶協議須要按照特定風格。所以在MQTT協議之上,咱們須要定義一套本身的通訊協議。就能夠有下面幾種選擇了、

1)  十六進制/二進制:

失去了可讀性,能夠將流量控制的比較小。單片開發可能會比較喜歡用這個。

 

2)  字符串:

這個會方便閱讀。對於高級語言開發者來講,字符串依舊不是最佳選擇。鍵值對(Key-value)纔是最優形式。

 

3)  JSON:

在這門語言中,一切都是對象。所以任何支持的類型均可以經過JSON來表示。例如字符串、數字、對象、數組等、

語法規則是:對象表示鍵值對、數據用逗號分開、花括號保存對象、方括號保存數組。

JSON層次結構簡潔清晰,便於閱讀和編寫,易於機器解析和生成,有效提高網絡傳輸效率。

 

4)  XML:

綜上,MQTT+JSON是最優解。

 

5、總結

MQTT基於異步發佈/訂閱的實現解耦了消息發佈者和訂閱者,基於二進制的實現節省了存儲空間及流量,同時擁有更好的消息處理機制。

MQTT協議是爲大量計算能力有限,且工做在低帶寬、不可靠的網絡的遠程傳感器和控制設備通信而設計的協議

 

以上 參考http://www.javashuo.com/article/p-waijxhik-kr.html

 

參考:http://www.javashuo.com/article/p-mscjejon-ge.html

 

補充幾個概念:

參考:https://www.jianshu.com/p/ecde412d2eeb

 

  • MQTT 客戶端

    一個使用 MQTT 協議的設備、應用程序等,它老是創建到服務器的網絡鏈接。

    • 能夠發佈信息,其餘客戶端能夠訂閱該信息

    • 訂閱其它客戶端發佈的消息

    • 退訂或刪除應用程序的消息

    • 斷開與服務器鏈接

  • MQTT 服務器

    MQTT 服務器以稱爲 Broker(消息代理),以是一個應用程序或一臺設備。它是位於消息發佈者 和訂閱者之間

    • 接受來自客戶端的網絡鏈接
    • 接受客戶端發佈的應用信息
    • 處理來自客戶端的訂閱和退訂請求
    • 向訂閱的客戶轉發應用程序消息
  • 主題(Topic)

    鏈接到一個應用程序消息的標籤,該標籤與服務器的訂閱相匹配。服務器會將消息發送給訂閱所匹配標籤的每一個客戶端。

    • 要訂閱的主題。一個主題能夠有多個級別,級別之間用斜槓字符分隔。例如,/worldemq/emqtt/emqx 是有效的主題。

    • 訂閱者的Topic name支持通配符#和+ :

      • # 支持一個主題內任意級別話題
      • +只匹配一個主題級別的通配符
    • 客戶端成功訂閱某個主題後,代理會返回一條 SUBACK 消息,其中包含一個或多個 returnCode 參數

  • 主題篩選器(Topic Filter)

    一個對主題名通配符篩選器,在訂閱表達式中使用,表示訂閱所匹配到的多個主題。

  • QoS(消息傳遞的服務質量水平)

    服務質量,標誌代表此主題範圍內的消息傳送到客戶端所需的一致程度。

    • 值 0:不可靠,消息基本上僅傳送一次,若是當時客戶端不可用,則會丟失該消息。
    • 值 1:消息應傳送至少 1 次。
    • 值 2:消息僅傳送一次。
  • 會話(Session)

    每一個客戶端與服務器創建鏈接後就是一個會話,客戶端和服務器之間有狀態交互。會話存在於一個網絡之間,也可能在客戶端和服務器之間跨越多個連續的網絡鏈接。

  • 訂閱(Subscription)

    訂閱包含主題篩選器(Topic Filter)和最大服務質量(QoS)。訂閱會與一個會話(Session)關聯。一個會話能夠包含多個訂閱。每個會話中的每一個訂閱都有一個不一樣的主題篩選器。

    • 客戶端在成功創建TCP鏈接以後,發送CONNECT消息,在獲得服務器端受權容許創建彼此鏈接的CONNACK消息以後,客戶端會發送SUBSCRIBE消息,訂閱感興趣的Topic主題列表(至少一個主題)
    • 訂閱的主題名稱採用UTF-8編碼,而後緊跟着對應的QoS值
  • 發佈(publish)

    控制報文是指從客戶端向服務端或者服務端向客戶端傳輸一個應用消息,MQTT 客戶端發送消息請求,發送完成後返回應用程序線程

    • 好比安卓的推送服務,還有一些即時通訊軟件如微信等也是採用的推送技術。
  • 負載(Payload)

    消息訂閱者所具體接收的內容

相關文章
相關標籤/搜索