天天看點

建立MQTT連接配接時如何設定參數?

作者:EMQ映雲科技

建立一個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連接配接參數的使用

連接配接位址

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倍時間内收到來自用戶端的任何包,則會認為和用戶端之間的連接配接出現了問題,此時伺服器便會斷開和用戶端的連接配接。

清除會話(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為 true 時表明遺囑消息是保留消息。MQTT伺服器會為每個主題存儲最新一條保留消息,以友善消息釋出後才上線的用戶端在訂閱主題時仍可以接收到該消息。

協定版本

使用較多的MQTT協定版本有MQTT v3.1、MQTT v3.1.1及MQTT v5.0。目前,MQTT 5.0已成為絕大多數物聯網企業的首選協定,我們建議初次接觸MQTT的開發者直接使用該版本。

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表示會話永遠不會過期。

連接配接屬性(Connect Properties)

MQTT 5.0還新引入了連接配接屬性的概念,進一步增強了協定的可擴充性。

如何建立一個安全的MQTT連接配接?

雖然MQTT協定提供了使用者名、密碼、Client ID等認證機制,但是這對于物聯網安全來說還遠遠不夠。基于傳統的TCP通信使用明文傳輸,資訊的安全性很難得到保證,資料也會存在被竊聽、篡改、僞造、冒充的風險。

SSL/TLS的出現很好的解決了通信中的風險問題,其以非對稱加密技術為主幹,混合了不同模式的加密方式,既保證了通信中消息都以密文傳輸,避免了被竊聽的風險,同時也通過簽名防止了消息被篡改。

不同MQTT伺服器啟用SSL/TLS的步驟都各有不同,EMQX内置了對TLS/SSL的支援,包括支援單/雙向認證、X.509證書、負載均衡SSL等多種安全認證。

單向認證是一種僅通過驗證伺服器證書來建立安全通信的方式,它能保證通信是加密的,但是不能驗證用戶端的真僞,通常需要與使用者名、密碼、Client ID等認證機制結合。

雙向認證是指在進行通信認證時要求服務端和用戶端都提供證書,雙方都需要進行身份認證,以確定通信中涉及的雙方都是受信任的。雙方彼此共享其公共證書,然後基于該證書執行驗證、确認。一些對安全性要求較高的應用場景,就需要開啟雙向SSL/TLS認證。

注意: 如果在浏覽器端使用MQTT over WebSocket進行安全連接配接的話,目前還暫不支援雙向認證通信。

結語

至此,我們對MQTT連接配接的建立及各個連接配接參數的作用已經有了深刻的了解。讀者可以根據本文所學嘗試上手使用MQTT協定,開始MQTT應用及服務開發,探索MQTT的更多進階應用。

繼續閱讀