背景
從本章開始,在沒有特殊說明的情況下,文章中的MQTT版本均為 3.1.1。
MQTT 協議是物聯網中常見的協議之一,"輕量級物聯網消息推送協議",MQTT同HTTP屬於第七層(應用層)。
對於網絡分層還不太熟悉的朋友請點擊:《網絡OSI七層模型及各層作用 與 TCP/IP》
參考:《物聯網網關中MQTT和Modbus之間有何區別 》、《MQTT 入門介紹》
文檔資料:《MQTT協議中文版資料》、《MQTT協議英文版資料》
MQTT 的發展歷史
在物聯網中,開源和開放標准是基本的要素。MQTT 的發展歷史大致如下:
- 1999 年,IBM 和合作伙伴共同發明了 MQTT 協議。
- 2004 年, MQTT.org 開放了論壇,供大家廣泛參與。
- 2011 年,IBM 建立了 Eclipse 開源項目 Paho ,並貢獻了代碼。Eclipse Paho 是 MQTT 的 Java 實現版本。
- 2013 年, OASIS MQTT 技術規范委員會成立。
- 2014 年,MQTT 正式成為推薦的物聯網傳輸協議標准。
概念
MQTT
是機器對機器(M2M
)/物聯網(IoT
)連接協議。它被設計為一個極其輕量級的發布/訂閱
消息傳輸協議。對於需要較小代碼占用空間和/或網絡帶寬非常寶貴的遠程連接非常有用,是專為受限設備和低帶寬、高延遲或不可靠的網絡而設計。這些原則也使該協議成為新興的“機器到機器”(M2M
)或物聯網(IoT
)世界的連接設備,以及帶寬和電池功率非常高的移動應用的理想選擇。例如,它已被用於通過衛星鏈路與代理通信的傳感器、與醫療服務提供者的撥號連接,以及一系列家庭自動化和小型設備場景。它也是移動應用的理想選擇,因為它體積小,功耗低,數據包最小,並且可以有效地將信息分配給一個或多個接收器。
為什么不選擇其他眾多網絡協議 ?
大多數開發人員已經熟悉 HTTP Web 服務。那么為什么不讓 IoT 設備連接到 Web 服務?設備可采用 HTTP 請求的形式發送其數據,並采用 HTTP 響應的形式從系統接收更新。這種請求和響應模式存在一些嚴重的局限性:
HTTP 是一種同步協議。客戶端需要等待服務器響應。Web 瀏覽器具有這樣的要求,但它的代價是犧牲了可伸縮性。在 IoT 領域,大量設備以及很可能不可靠或高延遲的網絡使得同步通信成為問題。異步消息協議更適合 IoT 應用程序。 傳感器發送讀數,讓網絡確定將其傳送到目標設備和服務的最佳路線和時間。
HTTP 是單向的。客戶端必須發起連接。在 IoT 應用程序中,設備或傳感器通常是客戶端,這意味着它們無法被動地接收來自網絡的命令。
HTTP 是一種 1-1 協議。客戶端發出請求,服務器進行響應。將消息傳送到網絡上的所有設備上,不但很困難,而且成本很高,而這是 IoT 應用程序中的一種常見使用情況。
- HTTP 是一種有許多標頭和規則的重量級協議。它不適合受限的網絡。
出於上述原因,大部分高性能、可擴展的系統都使用異步消息總線來進行內部數據交換,而不使用 Web 服務。事實上,企業中間件系統中使用的最流行的消息協議被稱為 AMQP(高級消息排隊協議)。但是,在高性能環境中,計算能力和網絡延遲通常不是問題。AMQP 致力於在企業應用程序中實現可靠性和互操作性。它擁有龐大的特性集,但不適合資源受限的 IoT 應用程序。
除了 AMQP 之外,還有其他流行的消息協議。例如,XMPP(Extensible Messaging and Presence Protocol,可擴展消息和狀態協議)是一種對等即時消息 (IM) 協議。它高度依賴於支持 IM 用例的特性,比如存在狀態和介質連接。與 MQTT 相比,它在設備和網絡上需要的資源都要多得多。
那么,MQTT 為什么如此輕量且靈活?因為MQTT 協議的一個關鍵特性是發布和訂閱模型。與所有消息協議一樣,它將數據的發布者與使用者分離。
我們先來看看一個典型的MQTT網絡拓撲結構長什么樣子,再來介紹有關概念。
角色
實現MQTT協議需要客戶端和服務器端通訊完成,在通訊過程中,MQTT協議中有三種身份:發布者(Publish)、代理(Broker)(服務器)、訂閱者(Subscribe)。其中,消息的發布者和訂閱者都是客戶端,消息代理是服務器,消息發布者可以同時是訂閱者。應用消息通過MQTT傳輸時,它們有關聯的服務質量(QoS)和主題(Topic)。
完整流程
- 1) 啟動服務器代理。
- 2) 訂閱者向服務器代理訂閱相關主題。
- 3) 發布者向服務器代理發布主題信息。
- 4) 服務器代理想所有訂閱該主題的訂閱者推送消息。
客戶端 Client
使用MQTT的程序或設備。客戶端總是通過網絡連接到服務端。它可以
- 1) 發布應用消息給其它相關的客戶端。
- 2) 訂閱以請求接受相關的應用消息
- 3) 取消訂閱以移除接受應用消息的請求。
- 4) 從服務端斷開連接。
服務端 Server
一個程序或設備,作為發送消息的客戶端和請求訂閱的客戶端之間的中介。服務端
- 1) 接受來自客戶端的網絡連接
- 2) 接受客戶端發布的應用消息
- 3) 處理客戶端的訂閱和取消訂閱請求。
- 4) 轉發應用消息給符合條件的客戶端訂閱。
有關術語
訂閱 Subscription
訂閱包含一個主題過濾器(Topic Filter)和一個最大的服務質量(QoS)等級。訂閱與單個會話(Session)關聯。會話可以包含多於一個的訂閱。會話的每個訂閱都有一個不同的主題過濾器。
主題名 Topic Name
附加在應用消息上的一個標簽,服務端已知且與訂閱匹配。服務端發送應用消息的一個副本給每一個匹配的客戶端訂閱。
主題名稱(Topic name)用來標識已發布消息的信息的渠道。訂閱者用它來確定接收到所關心的信息。它是一個分層的結構,用斜線“/”作為分隔符(這個有點類似於restful風格)。
主題過濾器 Topic Filter
訂閱中包含的一個表達式,用於表示相關的一個或多個主題。主題過濾器可以使用通配符。
主題還可以通過通配符進行過濾。其中,+可以過濾一個層級,而#只能出現在主題最后表示過濾任意級別的層級。
值得注意的是MQTT允許使用通配符訂閱主題,但是並不允許使用通配符廣播。
舉個例子:
building-b/floor-5:代表B樓5層的設備。
+/floor-5:代表任何一個樓的5層的設備。
building-b/#:代表B樓所有的設備。
會話 Session
客戶端和服務端之間的狀態交互。一些會話持續時長與網絡連接一樣,另一些可以在客戶端和服務端的多個連續網絡連接間擴展。
控制報文 MQTT Control Packet
通過網絡連接發送的信息數據包。MQTT規范定義了十四種不同類型的控制報文,其中一個(PUBLISH報文)用於傳輸應用消息。
MQTT傳輸的消息分為:主題(Topic)和負載(payload)兩部分:
- (1)Topic,可以理解為消息的類型,訂閱者訂閱(Subscribe)后,就會收到該主題的消息內容(payload);
- (2)payload,可以理解為消息的內容,是指訂閱者具體要使用的內容。
網絡結構
設計規范
由於物聯網的環境是非常特別的,所以MQTT遵循以下設計原則:
- (1)精簡,不添加可有可無的功能;
- (2)發布/訂閱(Pub/Sub)模式,方便消息在傳感器之間傳遞,一對多消息發布;
- (3)允許用戶動態創建主題,零運維成本;
- (4)把傳輸量降到最低以提高傳輸效率;
- (5)把低帶寬、高延遲、不穩定的網絡等因素考慮在內;
- (6)支持連續的會話控制;
- (7)理解客戶端計算能力可能很低;
- (8)提供服務質量管理;
- (9)假設數據不可知,不強求傳輸數據的類型與格式,保持靈活性。
特點
- 開放消息協議,簡單易實現
- 發布訂閱模式,一對多消息發布
- 基於TCP/IP網絡連接,提供有序,無損,雙向連接。
- 1字節固定報頭,2字節心跳報文,最小化傳輸開銷和協議交換,有效減少網絡流量。
- 消息QoS支持,可靠傳輸保證
應用
MQTT協議廣泛應用於物聯網、移動互聯網、智能硬件、車聯網、電力能源等領域。
- 物聯網M2M通信,物聯網大數據采集
- Android消息推送,WEB消息推送
- 移動即時消息,例如Facebook Messenger
- 智能硬件、智能家具、智能電器
- 車聯網通信,電動車站樁采集
- 智慧城市、遠程醫療、遠程教育
- 電力、石油與能源等行業市場
MQTT協議中的訂閱、主題、會話
一、訂閱(Subscription)
訂閱包含主題篩選器(Topic Filter)和最大服務質量(QoS)。訂閱會與一個會話(Session)關聯。一個會話可以包含多個訂閱。每一個會話中的每個訂閱都有一個不同的主題篩選器。
二、會話(Session)
每個客戶端與服務器建立連接后就是一個會話,客戶端和服務器之間有狀態交互。會話存在於一個網絡之間,也可能在客戶端和服務器之間跨越多個連續的網絡連接。
三、主題名(Topic Name)
連接到一個應用程序消息的標簽,該標簽與服務器的訂閱相匹配。服務器會將消息發送給訂閱所匹配標簽的每個客戶端。
四、主題篩選器(Topic Filter)
一個對主題名通配符篩選器,在訂閱表達式中使用,表示訂閱所匹配到的多個主題。
五、負載(Payload)
消息訂閱者所具體接收的內容。
MQTT-SN協議簡要介紹
這一章是在下載 MQTT代碼源碼中發現,並查閱資料后進行補充的。
MQTT-SN(Sensor Networks)是MQTT協議的傳感器版本,基於TCP協議的MQTT對有些傳感器來說還是負載太重了,這些傳感器可能只有幾十個字節的內存,無法運行TCP協議。MQTT-SN對MQTT對內存受限的微處理器做了適當的優化,使之能夠跑在這種處理器上。
也就是說,MQTT與MQTT-SN 之間需要轉換才能夠互通。轉換的操作由MQTT-SN的網關完成。
MQTT-SN名稱由來
原名是MQTT-S,但會引起人們的誤解,因此更名成MQTT-SN:
As part of the job of applying the same or similar license terms to the MQTT-S specification as those on the MQTT specification, we are proposing a small name change. The new name would be MQTT-SN, standing for exactly the same long name, MQTT for Sensor Networks. Some people had assumed that the S in MQTT-S stood for secure, so we hope this change will avoid that confusion. – Ian Craggs
MQTT-SN存在目的
MQTT for Sensor Networks is aimed at embedded devices on non-TCP/IP networks, such as Zigbee. MQTT-SN is a publish/subscribe messaging protocol for wireless sensor networks (WSN), with the aim of extending the MQTT protocol beyond the reach of TCP/IP infrastructure for Sensor and Actuator solutions.
針對適配傳感裝置(縮寫為SA)的特定版MQTT協議,一般運行在嵌入式電池驅動的電子元件中,傳輸通過基於IEEE 802.15.4規范無線低速網絡構成的無線傳感網絡(WSN),同樣具有企業級別特性具有以數據為核心的(data-centric)訂閱/發布特性。
總之,針對低功耗、電池驅動、處理存儲受限的設備、不支持TCP/IP協議棧網絡的電子器件而定制,比如常見的ZigBee(或XBee),對所依賴的底層傳輸網絡不可知,但只要網絡支持雙向數據傳輸和網關,都是可以支持較為上層的MQTT-SN協議傳輸。比如簡單數據報服務,只要支持一個源端點發送數據到一個特定目的地端點,這對支持MQTT-SN協議,就足夠了。廣播數據報傳輸服務也是必須的用於網關和終端的自動發現流程。為了降低廣播風暴,MQTT-SN定義了廣播路徑深度(廣播范圍或廣播半徑)。
一些名詞和術語
- topic id,主題標識符,兩個字節16位表示的自然數(java語言short類型,0-65535范圍),對應於主題topic name
- 網關/服務器(gateway/server),在MQTT-SN中統一稱之為網關,主要處理和MQTT-SN客戶端的交互,縮寫為網關
- MQTT-SN終端和客戶端(client),統一稱之為客戶端,其實也是嵌入式傳感設備,或電子元件,資源受限,在無線區域個人網中運行
- IEEE 802.15.4,完整棧的整個數據上限為128個字節,一般選擇UDP(相比20個字節的TCP協議,UDP報文頭部僅僅需要8個字節)協議傳輸數據
- 低速網絡/當前網絡,指的是LR-WPAN(low-rate wireless personal area network,),低速無線個人區域網絡
MQTT-SN VS MQTT
盡管MQTT-SN被設計成盡可能接近於MQTT,但那些低功耗、電池驅動、資源受限的設備所在網絡場景為低速帶寬、高連接失敗、物理層數據包上線為128字節。文檔提出了以下不同點:
- CONNECT消息被拆分成三個消息(CONNECT,WILLTIPIC,WILLMSG),后兩者用於客戶端傳遞遺囑主題和遺囑消息等
- 在PUBLISH消息中主題(topic name)被替換成兩個字節長度自然數(topic id),這個需要客戶端通過注冊流程進行獲取對應的topic id
- 預定義(提前定義)topic id和topic name,省去中間注冊流程,客戶端和網關要求提前在其固件中指定
- 協議引入的自動發現機制可幫助客戶端發現潛在的網關。若存在多個網關,彼此可協調是為主從互備或者負載均衡
- “clean session”即可作用於訂閱持久化,也被擴展作用於遺囑特性(遺囑主題和遺囑消息)
- 針對休眠設備增加離線保活機制支持,當有消息時代理需要緩存,客戶端被喚醒時再發送
MQTT-SN架構示意
在MQTT-SN架構圖中,存在三種組件:
- MQTT-SN 客戶端
- MQTT-SN 網關,可單獨存在,也可以被集成到MQTT服務器中。需要承擔MQTT-SN和MQTT協議之間的轉換工作
- MQTT-SN 轉發器,負責轉發當前客戶端數據到不可直接訪問的網關上去,針對客戶端而言網關不可直接訪問時,轉發器作用就凸顯。轉發器封裝MQTT-SN消息轉發給網關,解封來自網關的消息發送給客戶端。網關不能夠篡改原始數據。
MQTT-SN傳輸網關
MQTT-SN網關傳輸方式,下面的圖片一目了然。
- 透明網關,會為每一個客戶端都建立一個TCP連接到MQTT服務器的通道,這樣會較為耗費網關網絡資源,但模型簡單
- 聚合網關,只建立一條TCP連接通道到MQTT服務器上,所有的客戶端共享一個通道,很經濟的說。
網關需要抉擇哪些消息需要和遠程的MQTT Server進行交互,比如只選擇客戶端發送的PUBLISH、SUBSCRIBLE消息等。