建立一個 MQTT 連接配接是使用 MQTT 協定進行通信的第一步。為了保證高可擴充性,在建立連接配接時 MQTT 協定提供了豐富的連接配接參數,以友善開發者能建立滿足不同業務需求的物聯網應用。本文将詳細講解 MQTT 中各個連接配接參數的作用,幫助開發者邁出使用 MQTT 的第一步。
MQTT 連接配接的基本概念
MQTT 連接配接由用戶端向伺服器端發起。任何運作了 MQTT 用戶端庫的程式或裝置都是一個 MQTT 用戶端,而 MQTT 伺服器則負責接收用戶端發起的連接配接,并将用戶端發送的消息轉發到另外一些符合條件的用戶端。
用戶端與伺服器建立網絡連接配接後,需要先發送一個
CONNECT
資料包給伺服器。伺服器收到
CONNECT
包後會回複一個
CONNACK
給用戶端,用戶端收到
CONNACK
包後表示 MQTT 連接配接建立成功。如果用戶端在逾時時間内未收到伺服器的
CONNACK
資料包,就會主動關閉連接配接。
大多數場景下,MQTT 通過 TCP/IP 協定進行網絡傳輸,但是 MQTT 同時也支援通過 WebSocket 或者 UDP 進行網絡傳輸。
MQTT over TCP
TCP/IP 應用廣泛,是一種面向連接配接的、可靠的、基于位元組流的傳輸層通信協定。它通過 ACK 确認和重傳機制,能夠保證發送的所有位元組在接收時是完全一樣的,并且位元組順序也是正确的。
MQTT 通常基于 TCP 進行網絡通信,它繼承了 TCP 的很多優點,能穩定運作在低帶寬、高延時、及資源受限的環境下。
MQTT over WebSocket
近年來随着 Web 前端的快速發展,浏覽器新特性層出不窮,越來越多的應用可以在浏覽器端通過浏覽器渲染引擎實作,Web 應用的即時通信方式 WebSocket 也是以得到了廣泛的應用。
很多物聯網應用需要以 Web 的方式被使用,比如很多裝置監控系統需要使用浏覽器實時顯示裝置資料。但是浏覽器是基于 HTTP 協定傳輸資料的,也就無法使用 MQTT over TCP。
MQTT 協定在建立之初便考慮到了 Web 應用的重要性,它支援通過 MQTT over WebSocket 的方式進行 MQTT 通信。關于如何使用 MQTT over WebSocket,讀者可檢視部落格使用 WebSocket 連接配接 MQTT 伺服器。
MQTT 連接配接參數的使用
連接配接位址
MQTT 的連接配接位址通常包含 :伺服器 IP 或者域名、伺服器端口、連接配接協定。
基于 TCP 的 MQTT 連接配接
mqtt
是普通的 TCP 連接配接,端口一般為 1883。
mqtts
是基于 TLS/SSL 的安全連接配接,端口一般為 8883。
比如
mqtt://broker.emqx.io:1883
是一個基于普通 TCP 的 MQTT 連接配接位址。
基于 WebSocket 的連接配接
ws
是普通的 WebSocket 連接配接,端口一般為 8083。
wss
是基于 WebSocket 的安全連接配接,端口一般為 8084。
當使用 WebSocket 連接配接時,連接配接位址還需要包含 Path,EMQX 預設配置的 Path 是
/mqtt
。比如
ws://broker.emqx.io:8083/mqtt
是一個基于 WebSocket 的 MQTT 連接配接位址。
用戶端 ID(Client ID)
MQTT 伺服器使用 Client ID 識别用戶端,連接配接到伺服器的每個用戶端都必須要有唯一的 Client ID。Client ID 的長度通常為 1 至 23 個位元組的 UTF-8 字元串。
如果用戶端使用一個重複的 Client ID 連接配接至伺服器,将會把已使用該 Client ID 連接配接成功的用戶端踢下線。
使用者名與密碼(Username & Password)
MQTT 協定可以通過使用者名和密碼來進行相關的認證和授權,但是如果此資訊未加密,則使用者名和密碼将以明文方式傳輸。如果設定了使用者名與密碼認證,那麼最好要使用
mqtts
或
wss
協定。
大多數 MQTT 伺服器預設為匿名認證,匿名認證時使用者名與密碼設定為空字元串即可。
連接配接逾時(Connect Timeout)
連接配接逾時時長,收到伺服器連接配接确認前的等待時間,等待時間内未收到連接配接确認則為連接配接失敗。
保活周期(Keep Alive)
保活周期,是一個以秒為機關的時間間隔。用戶端在無封包發送時,将按 Keep Alive 設定的值定時向服務端發送心跳封包,確定連接配接不被服務端斷開。
在連接配接建立成功後,如果伺服器沒有在 Keep Alive 的 1.5 倍時間内收到來自用戶端的任何包,則會認為和用戶端之間的連接配接出現了問題,此時伺服器便會斷開和用戶端的連接配接。
更多細節可檢視部落格:MQTT 協定中的 Keep Alive 機制。
清除會話(Clean Session)
為
false
時表示建立一個持久會話,在用戶端斷開連接配接時,會話仍然保持并儲存離線消息,直到會話逾時登出。為
true
時表示建立一個新的臨時會話,在用戶端斷開時,會話自動銷毀。
持久會話避免了用戶端掉線重連後消息的丢失,并且免去了用戶端連接配接後重複的訂閱開銷。這一功能在帶寬小,網絡不穩定的物聯網場景中非常實用。
伺服器為持久會話儲存的消息數量取決于伺服器的配置,比如 EMQ 提供的免費的公共 MQTT 伺服器設定的離線消息儲存時間為 5 分鐘,最大消息數為 1000 條,且不儲存 QoS 0 消息。
注意: 持久會話恢複的前提是用戶端使用固定的 Client ID 再次連接配接,如果 Client ID 是動态的,那麼連接配接成功後将會建立一個新的持久會話。
遺囑消息(Last Will)
遺囑消息是 MQTT 為那些可能出現意外斷線的裝置提供的将遺囑優雅地發送給其他用戶端的能力。設定了遺囑消息消息的 MQTT 用戶端異常下線時,MQTT 伺服器會釋出該用戶端設定的遺囑消息。
意外斷線包括:因網絡故障,連接配接被服務端關閉;裝置意外掉電;裝置嘗試進行不被允許的操作而被服務端關閉連接配接等。
遺囑消息可以看作是一個簡化版的 MQTT 消息,它也包含 Topic、Payload、QoS、Retain 等資訊。
- 當裝置意外斷線時,遺囑消息将被發送至遺囑 Topic;
- 遺囑 Payload 是待發送的消息内容;
- 遺囑 QoS 與普通 MQTT 消息的 QoS 一緻;
- 遺囑 Retain 為
時表明遺囑消息是保留消息。MQTT 伺服器會為每個主題存儲最新一條保留消息,以友善消息釋出後才上線的用戶端在訂閱主題時仍可以接收到該消息。true
更多關于遺囑消息的介紹可檢視部落格:MQTT 遺囑消息(Will Message)的使用。
協定版本
使用較多的 MQTT 協定版本有 MQTT v3.1、MQTT v3.1.1 及 MQTT v5.0。目前,MQTT 5.0 已成為絕大多數物聯網企業的首選協定,我們建議初次接觸 MQTT 的開發者直接使用該版本。
感興趣的讀者可檢視 EMQ 提供的 MQTT 5.0 系列文章,了解 MQTT 5.0 相關特性的使用。
MQTT 5.0 新增連接配接參數
Clean Start & Session Expiry Interval
MQTT 5.0 中将 Clean Session 拆分成了 Clean Start 與 Session Expiry Interval。
Clean Start 用于指定連接配接時是建立一個全新的會話還是嘗試複用一個已存在的會話。為
true
時表示必須丢棄任何已存在的會話,并建立一個全新的會話;為
false
時表示必須使用與 Client ID 關聯的會話來恢複與用戶端的通信(除非會話不存在)。
Session Expiry Interval 用于指定網絡連接配接斷開後會話的過期時間。設定為 0 或未設定,表示斷開連接配接時會話即到期;設定為大于 0 的數值,則表示會話在網絡連接配接關閉後會保持多少秒;設定為 0xFFFFFFFF 表示會話永遠不會過期。
更多細節可檢視部落格:Clean Start 與 Session Expiry Interval。
連接配接屬性(Connect Properties)
MQTT 5.0 還新引入了連接配接屬性的概念,進一步增強了協定的可擴充性。更多細節可檢視部落格:MQTT 5.0 連接配接屬性。
如何建立一個安全的 MQTT 連接配接?
雖然 MQTT 協定提供了使用者名、密碼、Client ID 等認證機制,但是這對于物聯網安全來說還遠遠不夠。基于傳統的 TCP 通信使用明文傳輸,資訊的安全性很難得到保證,資料也會存在被竊聽、篡改、僞造、冒充的風險。
SSL/TLS 的出現很好的解決了通信中的風險問題,其以非對稱加密技術為主幹,混合了不同模式的加密方式,既保證了通信中消息都以密文傳輸,避免了被竊聽的風險,同時也通過簽名防止了消息被篡改。
不同 MQTT 伺服器啟用 SSL/TLS 的步驟都各有不同,EMQX 内置了對 TLS/SSL 的支援,包括支援單/雙向認證、X.509 證書、負載均衡 SSL 等多種安全認證。
單向認證是一種僅通過驗證伺服器證書來建立安全通信的方式,它能保證通信是加密的,但是不能驗證用戶端的真僞,通常需要與使用者名、密碼、Client ID 等認證機制結合。讀者可參考部落格EMQX MQTT 伺服器啟用 SSL/TLS 安全連接配接來建立一個安全的單向認證 MQTT 連接配接。
雙向認證是指在進行通信認證時要求服務端和用戶端都提供證書,雙方都需要進行身份認證,以確定通信中涉及的雙方都是受信任的。 雙方彼此共享其公共證書,然後基于該證書執行驗證、确認。一些對安全性要求較高的應用場景,就需要開啟雙向 SSL/TLS 認證。讀者檢視部落格EMQX 啟用雙向 SSL/TLS 安全連接配接了解如何建立一個安全的雙向認證 MQTT 連接配接。
注意: 如果在浏覽器端使用 MQTT over WebSocket 進行安全連接配接的話,目前還暫不支援雙向認證通信。