MQTT基础--MQTT 客户端和代理以及 MQTT 服务器和连接建立说明:第 3 部分
上一節我們解釋了發布/訂閱模式的工作原理以及它是如何在 MQTT 中應用的。
以下是核心概念的快速回顧:
-
發布/訂閱將發送消息的客戶端(發布者)與接收消息的客戶端(訂閱者)分離。
-
MQTT 使用消息的主題(主題)來確定哪個消息發送到哪個客戶端(訂閱者)。主題是一個分層結構的字符串,可用于過濾和路由消息
我們的上一篇文章為您提供了發布/訂閱模型的高級視圖,以及它與傳統消息隊列的不同之處。這篇文章采用了一種實用的方法,并包含了有關 MQTT 的基本知識:術語 MQTT 客戶端和代理的定義、MQTT 連接的基礎知識、連接消息及其參數,以及通過代理的確認建立連接。
MQTT Client 和 MQTT 代理 簡介
因為 MQTT 將發布者與訂閱者分離,所以客戶端連接始終由代理處理。在深入了解這些連接的細節之前,讓我們先弄清楚客戶端和代理的含義。
客戶(Client) 當我們談論客戶端時,我們幾乎總是指MQTT 客戶端。發布者和訂閱者都是 MQTT 客戶端。發布者和訂閱者標簽是指客戶端當前是發布消息還是訂閱接收消息(發布和訂閱功能也可以在同一個 MQTT 客戶端中實現)。MQTT 客戶端是運行 MQTT 庫并通過網絡連接到MQTT 代理的任何設備(從微控制器到成熟的服務器)。例如,MQTT 客戶端可以是一個非常小的、資源受限的設備,它通過無線網絡連接,并具有一個最低限度的庫。MQTT 客戶端也可以是運行圖形 MQTT 客戶端以進行測試的典型計算機。基本上,任何通過 TCP/IP 堆棧使用 MQTT 的設備都可以稱為 MQTT 客戶端。MQTT 協議的客戶端實現非常直接和精簡。易于實施是 MQTT 非常適合小型設備的原因之一。MQTT 客戶端庫可用于多種編程語言。例如,Android、Arduino、C、C++、C#、Go、iOS、Java、JavaScript 和 .NET。
經紀人(Broke) MQTT 客戶端的對應物是 MQTT 代理。代理是任何發布/訂閱協議的核心。根據實現的不同,代理可以處理多達數百萬個并發連接的 MQTT 客戶端。
代理負責接收所有消息,過濾消息,確定每條消息的訂閱者,并將消息發送給這些訂閱的客戶端。代理還保存所有具有持久會話的客戶端的會話數據,包括訂閱和錯過的消息(更多詳細信息)。代理的另一個職責是客戶端的身份驗證和授權。通常,代理是可擴展的,這有助于自定義身份驗證、授權和集成到后端系統。集成尤為重要,因為代理經常是直接暴露在互聯網上的組件,處理大量客戶端,需要將消息傳遞給下游分析和處理系統。正如在以前的帖子,訂閱所有消息并不是一個真正的選擇。簡而言之,代理是每條消息都必須通過的中心樞紐。因此,您的代理必須具有高度可擴展性、可集成到后端系統、易于監控并且(當然)具有抗故障能力,這一點很重要。
MQTT 連接
MQTT 協議基于 TCP/IP。客戶端和代理都需要有一個 TCP/IP 堆棧。
MQTT 連接始終在一個客戶端和代理之間。客戶端從不直接相互連接。為了啟動連接,客戶端向代理發送 CONNECT 消息。代理以 CONNACK 消息和狀態代碼進行響應。建立連接后,代理將保持打開狀態,直到客戶端發送斷開連接命令或連接中斷。
?通過 NAT 的 MQTT 連接
在許多常見用例中,MQTT 客戶端位于路由器后面,該路由器使用網絡地址轉換 (NAT) 將專用網絡地址(如 192.168.xx、10.0.xx)轉換為面向公眾的地址。正如我們已經提到的,MQTT 客戶端通過向代理發送 CONNECT 消息來啟動連接。因為代理有一個公共地址并保持連接打開以允許雙向發送和接收消息(在初始 CONNECT 之后),所以位于 NAT 后面的客戶端完全沒有問題。
客戶端使用 CONNECT 消息發起連接
現在讓我們看一下MQTT CONNECT命令消息。為了啟動連接,客戶端向代理發送命令消息。如果此 CONNECT 消息格式不正確(根據 MQTT 規范)或在打開網絡套接字和發送連接消息之間經過了太多時間,則代理將關閉連接。此行為阻止了可能減慢代理速度的惡意客戶端。 一個正常的 MQTT 3 客戶端發送一條包含以下內容:
?CONNECT 消息中包含的一些信息對于 MQTT 庫的實現者可能比該庫的用戶更感興趣。有關所有詳細信息,請查看MQTT 3.1.1 規范。
我們將重點關注以下選項:
客戶 ID(client Id)
客戶端標識符 (ClientId)標識連接到 MQTT 代理的每個 MQTT 客戶端。代理使用 ClientId 來標識客戶端和客戶端的當前狀態。因此,此 Id 對于每個客戶端和代理應該是唯一的。在 MQTT 3.1.1 中,如果您不需要代理持有狀態,您可以發送一個空的 ClientId。空的 ClientId 導致沒有任何狀態的連接。在這種情況下,必須將 clean session 標志設置為 true,否則代理將拒絕連接。
清除會話(cleanSession)
干凈會話標志告訴代理客戶端是否要建立持久會話。在持久會話中 (CleanSession = false),代理存儲客戶端的所有訂閱以及訂閱服務質量 (QoS)級別 1 或 2 的客戶端的所有錯過消息。如果會話不是持久的 (CleanSession = true ),代理不會為客戶端存儲任何內容,并從任何先前的持久會話中清除所有信息。
用戶名密碼(username/password)
MQTT 可以發送用戶名和密碼進行客戶端認證和授權。但是,如果此信息未加密或散列(通過實現或 TLS),則密碼將以純文本形式發送。我們強烈建議將用戶名和密碼與安全傳輸一起使用。當使用HiveMQ 這樣的代理可以使用 SSL 證書對客戶端進行身份驗證,因此不需要用戶名和密碼。
遺囑留言(last will)
最后遺囑消息是 MQTT 的遺囑和遺囑 (LWT) 功能的一部分。當客戶端異常斷開連接時,此消息會通知其他客戶端。當客戶端連接時,它可以以 MQTT 消息和 CONNECT 消息中的主題的形式向代理提供最后的遺囑。如果客戶端不正常斷開連接,代理會代表客戶端發送 LWT 消息。
保持連接(keep Alive)
保持活動是客戶端指定并在連接建立時與代理通信的時間間隔(以秒為單位)。這個間隔定義了代理和客戶端可以忍受的最長時間而不發送消息。客戶端承諾向代理發送常規 PING 請求消息。代理以 PING 響應進行響應。此方法允許雙方確定另一方是否仍然可用。
基本上,這就是從 MQTT 3.1.1 客戶端連接到 MQTT 代理所需的全部信息。各個庫通常具有您可以配置的其他選項。例如,隊列消息在特定實現中的存儲方式。
帶有 CONNACK 消息的代理響應
當代理收到 CONNECT 消息時,它有義務以 CONNACK 消息進行響應。
CONNACK 消息包含兩個數據條目:
-
會話呈現標志
-
連接返回碼
會話存在標志
會話存在標志告訴客戶端代理是否已經有一個可從先前與客戶端的交互中獲得的持久會話。當客戶端連接并將 Clean Session 設置為 true 時,會話存在標志始終為 false,因為沒有可用的會話。如果客戶端在 Clean Session 設置為 false 的情況下連接,則有兩種可能性: 如果會話信息可用于 clientId。并且代理已經存儲了會話信息,會話存在標志為真。否則,如果代理沒有 clientId 的任何會話信息,則會話存在標志為 false。此標志是在 MQTT 3.1.1 中添加的,以幫助客戶端確定他們是否需要訂閱主題,或者主題是否仍存儲在持久會話中。
連接返回碼
CONNACK消息中的第二個標志 是連接確認標志。這個標志包含一個返回碼,告訴客戶端連接嘗試是否成功。
?以下是返回代碼一目了然:。
| 0 | 已接受連接 |
| 1 | 連接被拒絕,協議版本不可接受 |
| 2 | 連接被拒絕,標識符被拒絕 |
| 3 | 連接被拒絕,服務器不可用 |
| 4 | 連接被拒絕,用戶名或密碼錯誤 |
| 5 | 連接被拒絕,未授權 |
有關每個代碼的更詳細說明,請參閱MQTT 規范。
總結
以上是生活随笔為你收集整理的MQTT基础--MQTT 客户端和代理以及 MQTT 服务器和连接建立说明:第 3 部分的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 校园二手交易平台项目总结 201
- 下一篇: 前端有用网站合集