爲何 MQTT 是最適合物聯網的網絡協議php
物聯網 (IoT) 設備必須鏈接互聯網。經過鏈接到互聯網,設備就能相互協做,以及與後端服務協同工做。互聯網的基礎網絡協議是 TCP/IP。MQTT(消息隊列遙測傳輸) 是基於 TCP/IP 協議棧而構建的,已成爲 IoT 通訊的標準。數據庫
MQTT 最初由 IBM 於上世紀 90 年代晚期發明和開發。它最初的用途是將石油管道上的傳感器與衛星相連接。顧名思義,它是一種支持在各方之間異步通訊的消息協議。異步消息協議在空間和時間上將消息發送者與接收者分離,所以能夠在不可靠的網絡環境中進行擴展。雖然叫作消息隊列遙測傳輸,但它與消息隊列毫無關係,而是使用了一個發佈和訂閱的模型。在 2014 年底,它正式成爲了一種 OASIS 開放標準,並且在一些流行的編程語言中受到支持(經過使用多種開源實現)。編程
MQTT 是一種輕量級的、靈活的網絡協議,致力於爲 IoT 開發人員實現適當的平衡:後端
爲了瞭解爲何 MQTT 如此適合 IoT 開發人員,咱們首先來分析一下爲何其餘流行網絡協議未在 IoT 中獲得成功應用。瀏覽器
大多數開發人員已經熟悉 HTTP Web 服務。那麼爲何不讓 IoT 設備鏈接到 Web 服務?設備可採用 HTTP 請求的形式發送其數據,並採用 HTTP 響應的形式從系統接收更新。這種請求和響應模式存在一些嚴重的侷限性:服務器
出於上述緣由,大部分高性能、可擴展的系統都使用異步消息總線來進行內部數據交換,而不使用 Web 服務。事實上,企業中間件系統中使用的最流行的消息協議被稱爲 AMQP(高級消息排隊協議)。可是,在高性能環境中,計算能力和網絡延遲一般不是問題。AMQP 致力於在企業應用程序中實現可靠性和互操做性。它擁有龐大的特性集,但不適合資源受限的 IoT 應用程序。網絡
除了 AMQP 以外,還有其餘流行的消息協議。例如,XMPP(Extensible Messaging and Presence Protocol,可擴展消息和狀態協議)是一種對等即時消息 (IM) 協議。它高度依賴於支持 IM 用例的特性,好比存在狀態和介質鏈接。與 MQTT 相比,它在設備和網絡上須要的資源都要多得多。session
那麼,MQTT 爲何如此輕量且靈活?MQTT 協議的一個關鍵特性是發佈和訂閱模型。與全部消息協議同樣,它將數據的發佈者與使用者分離。eclipse
MQTT 協議在網絡中定義了兩種實體類型:一個消息代理和一些客戶端。代理是一個服務器,它從客戶端接收全部消息,而後將這些消息路由到相關的目標客戶端。客戶端是可以與代理交互來發送和接收消息的任何事物。客戶端能夠是現場的 IoT 傳感器,或者是數據中心內處理 IoT 數據的應用程序。
由於 MQTT 消息是按主題進行組織的,因此應用程序開發人員能靈活地指定某些客戶端只能與某些消息交互。例如,傳感器將在 「sensor_data」 主題範圍內發佈讀數,並訂閱 「config_change」 主題。將傳感器數據保存到後端數據庫中的數據處理應用程序會訂閱 「sensor_data」 主題。管理控制檯應用程序能接收系統管理員的命令來調整傳感器的配置,好比靈敏度和採樣頻率,並將這些更改發佈到 「config_change」 主題。(參閱圖 1。)
同時,MQTT 是輕量級的。它有一個用來指定消息類型的簡單標頭,有一個基於文本的主題,還有一個任意的二進制有效負載。應用程序可對有效負載採用任何數據格式,好比 JSON、XML、加密二進制或 Base64,只要目標客戶端可以解析該有效負載。
開始進行 MQTT 開發的最簡單工具是 Python mosquitto 模塊,該模塊包含在 Eclipse Paho 項目 中,提供了多種編程語言格式的 MQTT SDK 和庫。它包含一個能在本地計算機上運行的 MQTT 代理,還包含使用消息與代理交互的命令行工具。能夠從 mosquitto 網站 下載並安裝 mosquitto 模塊。
mosquitto 命令在本地計算機上運行 MQTT 代理。也可使用 -d 選項在後臺運行它。
$ mosquitto -d
接下來,在另外一個終端窗口中,可使用 mosquitto_sub 命令鏈接到本地代理並訂閱一個主題。運行該命令後,它將等待從訂閱的主題接收消息,並打印出全部消息。
$ mosquitto_sub -t "dw/demo"
在另外一個終端窗口中,可使用 mosquitto_pub 命令鏈接到本地代理,而後向一個主題發佈一條消息。
$ mosquitto_pub -t "dw/demo" -m "hello world!"
如今,運行 mosquitto_sub 的終端會在屏幕上打印出 「hello world!」。您剛纔使用 MQTT 代理髮送並接收了一條消息!
固然,在生產系統中,不能使用本地計算機做爲代理。相反,可使用 IBM Bluemix Internet of Things Platform 服務,這是一種可靠的按需服務,功能與 MQTT 代理相似。要進一步瞭解這個 Bluemix 服務如何集成並使用 MQTT 做爲與設備和應用程序通訊的協議,請參閱 該服務的文檔。)
IBM Bluemix Internet of Things Platform 服務 的工做原理以下。
使用遠程 MQTT 代理時,須要將代理的主機名和身份驗證憑證傳遞給 mosquitto_sub 和 mosquitto_pub 命令。例如,下面的命令使用了 Bluemix 提供的用戶名和密碼,訂閱咱們的 Internet of Things Platform 服務上的 demo 主題:
$ mosquitto_sub -t "demo" -h host.iotp.mqtt.bluemix.com -u username -P password
有關使用 mosquitto 工具的更多選擇,以及如何使用 mosquitto API 建立本身的 MQTT 客戶端應用程序,請參閱 mosquitto 網站 上的文檔。
有了必要的工具後,讓咱們來更深刻地研究 MQTT 協議。
MQTT 是一種鏈接協議,它指定了如何組織數據字節並經過 TCP/IP 網絡傳輸它們。但實際上,開發人員並不須要瞭解這個鏈接協議。咱們只須要知道,每條消息有一個命令和數據有效負載。該命令定義消息類型(例如 CONNECT 消息或 SUBSCRIBE 消息)。全部 MQTT 庫和工具都提供了直接處理這些消息的簡單方法,並能自動填充一些必需的字段,好比消息和客戶端 ID。
首先,客戶端發送一條 CONNECT 消息來鏈接代理。CONNECT 消息要求創建從客戶端到代理的鏈接。CONNECT 消息包含如下內容參數。
參數 | 說明 |
cleanSession | 此標誌指定鏈接是不是持久性的。持久會話會將全部訂閱和可能丟失的消息(具體取決於 QoS) 都存儲在代理中。(請參閱 表 3 獲取 QoS 的描述。) |
username | 代理的身份驗證和受權憑證。 |
password | 代理的身份驗證和受權憑證。 |
lastWillTopic | 鏈接意外中斷時,代理會自動向某個主題發送一條 「last will」 消息。 |
lastWillQos | 「last will」 消息的 QoS。(請參閱 表 3 來查看 QoS 的描述。) |
lastWillMessage | 「last will」 消息自己。 |
keepAlive | 這是客戶端經過 ping 代理來保持鏈接有效所需的時間間隔。 |
客戶端收到來自代理的一條 CONNACK 消息。CONNACK 消息包含如下內容參數。
參數 | 說明 |
sessionPresent | 此參數代表鏈接是否已有一個持久會話。也就是說,鏈接已訂閱了主題,並且會接收丟失的消息。 |
returnCode | 0 表示成功。其餘值指出了失敗的緣由。 |
創建鏈接後,客戶端而後會向代理髮送一條或多條 SUBSCRIBE 消息,代表它會從代理接收針對某些主題的消息。消息能夠包含一個或多個重複的參數。如表 3。
參數 | 說明 |
qos | qos(服務質量或 QoS)標誌代表此主題範圍內的消息傳送到客戶端所需的一致程度。
|
topic | 要訂閱的主題。一個主題能夠有多個級別,級別之間用斜槓字符分隔。例如,「dw/demo」 和 「ibm/bluemix/mqtt」 是有效的主題。 |
客戶端成功訂閱某個主題後,代理會返回一條 SUBACK 消息,其中包含一個或多個 returnCode 參數。
參數 | 說明 |
returnCode | SUBCRIBE 命令中的每一個主題都有一個返回代碼。返回值以下所示。
|
與 SUBSCRIBE 消息對應,客戶端也能夠經過 UNSUBSCRIBE 消息取消訂閱一個或多個主題。
參數 | 說明 |
topic | 此參數可重複用於多個主題。 |
客戶端可向代理髮送 PUBLISH 消息。該消息包含一個主題和數據有效負載。代理而後將消息轉發給全部訂閱該主題的客戶端。
參數 | 說明 |
topicName | 發佈的消息的相關主題。 |
qos | 消息傳遞的服務質量水平。(請參閱 表 3 來查看 QoS 的描述。) |
retainFlag | 此標誌代表代理是否保留該消息做爲針對此主題的最後一條已知消息。 |
payload | 消息中的實際數據。它能夠是文本字符串或二進制大對象數據。 |
MQTT 的優點在於它的簡單性。在可使用的主題類型或消息有效負載上沒有任何限制。這支持一些有趣的用例。例如,請考慮如下問題:
如何使用 MQTT 發送 1-1 消息?雙方能夠協商使用一個特定於它們的主題。例如,主題名稱能夠包含兩個客戶端的 ID,以確保它的惟一性。
客戶端如何傳輸它的存在狀態?系統能夠爲 「presence」 主題協商一個命名約定。例如,「presence/client-id」 主題能夠擁有客戶端的存在狀態信息。當客戶端創建鏈接時,將該消息被設置爲 true,在斷開鏈接時,該消息被設置爲 false。客戶端也能夠將一條 last will 消息設置爲 false,以便在鏈接丟失時設置該消息。代理能夠保留該消息,讓新客戶端可以讀取該主題並找到存在狀態。
如何保護通訊?客戶端與代理的鏈接能夠採用加密 TLS 鏈接,以保護傳輸中的數據。此外,由於 MQTT 協議對有效負載數據格式沒有任何限制,因此係統能夠協商一種加密方法和密鑰更新機制。在這以後,有效負載中的全部內容能夠是實際 JSON 或 XML 消息的加密二進制數據。
本文從技術角度介紹了 MQTT 協議。您瞭解了 MQTT 是什麼,MQTT 爲何適合 IoT 應用程序,以及如何開始開發使用 MQTT 的應用程序。
【來源】