由於工做須要,瞭解了一下MQTT。順便記下來,如今還不會用。html
MQTT(Message Queuing Telemetyr Transport 消息隊列遙測傳輸協議):基於發佈/訂閱(Publish/Subscribe)模式的輕量級通信協議,該協議構建於TCP/IP協議之上。數組
MQTT運行於TCP之上,屬於應用層協議。安全
每條MQTT命令消息的消息頭都包含一個固定的報頭,有些消息會攜帶一個可變報文頭和一個負荷。消息格式以下:服務器
固定報文頭|可變報文頭|負荷微信
最少有兩個字節,第一個字節包含消息的類型(Message Type)和QoS級別等標誌位。第二個字節開始是剩餘長度字節,該長度是後面的可變報文頭加消息負載的總長度,該字段最多容許四個字節。網絡
剩餘長度字段單個字節的最大值爲0x7F. 也就是127個字節。MQTT協議規定,單個字節的最高位若是是1,表示後續還有字節存在,第八位起延續位的做用。異步
因爲MQTT協議最多使用四個字節表示剩餘長度,而且最後一個字節的最大值只能是0x7F,而不是0xFF。因此能發送的最大消息長度是256MB,而不是512MB。工具
主要包含協議名,協議版本,鏈接標誌,心跳間隔時間,鏈接返回碼,主題名等。ui
實際上能夠理解爲消息的主體。當MQTT發送的消息類型是CONNECT(鏈接)、PUBLISH(發佈)、SUBSCRIBE(訂閱)、SUBACK(訂閱確認)、UBSUNSCRIBE(取消訂閱)時會帶有負荷。編碼
固定報文頭中的第一個字節包含鏈接標誌,鏈接標誌用來區分MQTT的消息類型。MQTT協議擁有14中不一樣的消息類型。以下圖:
可簡單分爲鏈接及終止、發佈和訂閱、Qos2消息的機制以及各類確認ACK。
MQTT消息質量有三個等級,QoS 0、Qos 一、Qos 2。
Qos 0:最多分發一次,消息的傳遞徹底依賴底層的TCP/IP網絡,協議裏沒有定義應答和重試。消息只會到達服務端一次,要麼就沒到達。
Qos 1:至少分發一次、服務器的消息接收由PUBACK消息進行確認,若是通訊鏈路或設備異常,或指定時間內沒有收到確認消息,發送端會重發這條在消息頭中設置了Dup位的消息。
Qos 2:只分發一次。最高級別的消息傳遞,消息丟失和重複都是不可接受的,使用這個服務質量等級會有額外的開銷。
在可變報文頭的鏈接標誌位字段(Connect Flags)裏面有三個will標誌位:Will Flag Will Qos和Retain Flag。這些will字段用於監控客戶端與服務器之間的鏈接情況。
遺願消息:服務器與客戶端通訊時,當遇到異常或客戶端心跳超時的狀況,MQTT服務器會替客戶端發佈一個will消息。固然若是服務器收到來自客戶端的DISCONNECT消息則不會觸發wiwll消息的發送。所以will字段能夠應用於設備掉線後通知用戶的場景
MQTT客戶端能夠設置一個心跳間隔時間(keep Alive Timer),表示在每一個心跳檢測時間內發送一條消息。若是在這個時間週期內,沒有業務數據相關的消息,客戶端會發送一個PINGREQ消息,相應的,服務器會返回一個PINGRESP消息進行確認。
若是服務器在一個半(1.5)個心跳間隔時間週期內沒有收到來自客戶端的消息,就會斷開與客戶端的鏈接。心跳間隔時間最大值能夠設置爲18個小時,8表示客戶端不會斷開。
發佈/訂閱模式解耦了發佈消息的客戶(發佈者)和訂閱消息的客戶(訂閱者)之間的關係。發佈者與訂閱者並不須要直接創建聯繫。
這個模式的好處有:
1) 發佈者與訂閱者只須要知道同一個消息代理便可。
2) 發佈者與訂閱者不須要直接交互,不須要同時在線。
MQTT基於二進制而不是字符串。固定報文頭僅有兩個字節,相比於其餘協議(HTTPS 和XMPP都是基於字符串實現,有冗長的頭部),發送一條消息更省流量
因爲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協議之上,咱們須要定義一套本身的通訊協議。就能夠有下面幾種選擇了、
失去了可讀性,能夠將流量控制的比較小。單片開發可能會比較喜歡用這個。
這個會方便閱讀。對於高級語言開發者來講,字符串依舊不是最佳選擇。鍵值對(Key-value)纔是最優形式。
在這門語言中,一切都是對象。所以任何支持的類型均可以經過JSON來表示。例如字符串、數字、對象、數組等、
語法規則是:對象表示鍵值對、數據用逗號分開、花括號保存對象、方括號保存數組。
JSON層次結構簡潔清晰,便於閱讀和編寫,易於機器解析和生成,有效提高網絡傳輸效率。
綜上,MQTT+JSON是最優解。
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)
鏈接到一個應用程序消息的標籤,該標籤與服務器的訂閱相匹配。服務器會將消息發送給訂閱所匹配標籤的每一個客戶端。
要訂閱的主題。一個主題能夠有多個級別,級別之間用斜槓字符分隔。例如,/world
和 emq/emqtt/emqx
是有效的主題。
訂閱者的Topic name支持通配符#和+ :
客戶端成功訂閱某個主題後,代理會返回一條 SUBACK 消息,其中包含一個或多個 returnCode 參數
主題篩選器(Topic Filter)
一個對主題名通配符篩選器,在訂閱表達式中使用,表示訂閱所匹配到的多個主題。
QoS(消息傳遞的服務質量水平)
服務質量,標誌代表此主題範圍內的消息傳送到客戶端所需的一致程度。
會話(Session)
每一個客戶端與服務器創建鏈接後就是一個會話,客戶端和服務器之間有狀態交互。會話存在於一個網絡之間,也可能在客戶端和服務器之間跨越多個連續的網絡鏈接。
訂閱(Subscription)
訂閱包含主題篩選器(Topic Filter)和最大服務質量(QoS)。訂閱會與一個會話(Session)關聯。一個會話能夠包含多個訂閱。每個會話中的每一個訂閱都有一個不一樣的主題篩選器。
發佈(publish)
控制報文是指從客戶端向服務端或者服務端向客戶端傳輸一個應用消息,MQTT 客戶端發送消息請求,發送完成後返回應用程序線程
負載(Payload)
消息訂閱者所具體接收的內容