MQTT通信協議介紹

語言: CN / TW / HK

一:MQTT協議介紹

MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通訊協議,它是一種輕量級的、基於代理的“發佈/訂閲”模式的消息傳輸協議。其具有協議簡潔小巧可擴展性強省流量、等優點。可在不可靠的網絡環境中進行擴展,適用於設備硬件存儲空間或網絡帶寬有限的場景。使用MQTT協議,消息發送者與接收者不受時間和空間的限制。物聯網平台支持設備使用MQTT協議接入。

二:MQTT協議的主要特點

1、使用發佈/訂閲消息模式,提供一對多的消息發佈,解除應用程序耦合

2、使用 TCP/IP 提供網絡連接

3、有三種級別的消息發佈服務質量QoS(Quality of Service)

  • “至多一次”(Qos = 0),消息發佈完全依賴底層 TCP/IP 網絡。會發生消息丟失或重複。這一級別可用於如下情況,環境傳感器數據,丟失一次讀記錄無所謂,因為不久後還會有第二次發送。

  • “至少一次”(Qos = 1),確保消息到達,但消息重複可能會發生。

  • “只有一次”(Qos = 2),確保消息到達一次。消息丟失和重複都是不可接受的,使用這個服務質量等級會有額外的開銷。

三:MQTT協議的核心角色

MQTT 協議主要有三大核心角色:發佈者(Publisher)、Broker代理服務器(轉發者)訂閲者(Subscriber) 。其中消息的發佈者和訂閲者都是客户端(Client)角色,消息代理是服務器,消息發佈者可以同時是訂閲者。 當Client發佈某個主題的消息時,Broker會將該消息分發給任何已訂閲該主題的Client。

image.png

MQTT服務器

MQTT服務端通常是一台服務器。它是MQTT信息傳輸的樞紐,負責將MQTT客户端發送來的信息傳遞給MQTT客户端。MQTT服務端還負責管理MQTT客户端。確保客户端之間的通訊順暢,保證MQTT消息得以正確接收和準確投遞。

MQTT客户端

MQTT客户端可以向服務端發佈信息,也可以從服務端收取信息。我們把客户端發送信息的行為成為“發佈”信息。而客户端要想從服務端收取信息,則首先要向服務端“訂閲”信息。“訂閲”信息這一操作很像我們在微信中訂閲的公眾號,當公眾號更新時,微信會向訂閲了該公眾號的用户發送信息,告訴他們有文章更新了。

MQTT主題

剛剛我們在講解MQTT客户端訂閲信息時,使用了用户在微信中訂閲公眾號的這個例子。在MQTT通訊中,客户端所訂閲的肯定不是一個個公眾號,而是一個個“主題”。MQTT服務端在管理MQTT信息通訊時,就是使用“主題”來控制的。

四:連接MQTT服務端

MQTT客户端要想通訊,必須經過MQTT服務端。因此MQTT客户端無論是發佈消息還是訂閲消息,首先都要連接MQTT服務端。下面我們看一下MQTT客户端連接服務端的詳細過程。

1、首先MQTT客户端將會向服務端發送連接請求。該請求實際上是一個包含有連接請求信息的數據包。這個數據包的官方名稱為CONNECT image.png 2、MQTT服務端收到客户端連接請求後,會向客户端發送連接確認。同樣的,該確認也是一個數據包。這個數據包官方名稱為CONNACK

image.png

以上就是MQTT客户端在連接服務端的兩步操作。接下來,我們一起來了解一下客户端在連接服務端時所發送的CONNECT報文內容。

clientId – 客户端ID

ClientId是MQTT客户端的標識。MQTT服務端用該標識來識別客户端。因此ClientId必須是獨立的。如果兩個MQTT客户端使用相同ClientId標識,服務端會把它們當成同一個客户端來處理。通常ClientId是由一串字符所構成的

username(用户名)和password(密碼)

這裏的用户名和密碼是用於客户端連接服務端時進行認證需要的。有些MQTT服務端需要客户端在連接時提供用户名和密碼。只有客户端正確提供了用户名和密碼後,才能連接服務端。否則服務端將會拒絕客户端連接,那麼客户端也就無法發佈和訂閲消息了。

username(用户名)和password(密碼)是可選的CONNECT信息。也就是説,有些服務端開啟了客户端用户密碼認證,這種服務端需要客户端在連接時正確提供認證信息才能連接。當然,那些沒有開啟用户密碼認證的服務端無需客户端提供用户名和密碼認證信息

cleanSession – 清除會話

要説明cleanSession的具體含義,首先要從MQTT網絡環境講起。MQTT客户端與服務端的連接可能不是非常穩定,在不穩定的網絡環境下,要想保證所有信息傳輸都能夠做到準確無誤,這是非常困難的。

為了保證重要的MQTT報文可以被客户端準確無誤的收到。在服務端向客户端發送報文後,客户端會向服務端返回一個確認報文。如果服務端沒有收到客户端返回的確認報文,那麼服務端就會認為剛剛發送給客户端的報文沒有被準確無誤的送達。在這種情況下,服務端將會執行以下兩個操作:

1、將尚未被客户端確認的報文保存起來

2、再次嘗試向客户端發送報文,並且再次等待客户端發來確認信息。

如果 cleanSession 被設置為“true”。那麼服務端不需要客户端確認收到報文,也不會保存任何報文。在這種情況下,即使客户端錯過了服務端發來的報文,也沒辦法讓服務端再次發送報文。 反過來,如果我們將 cleanSession 設置為”false”。那麼服務端就知道,後續通訊中,客户端可能會要求我保存沒有收到的報文。

keepAlive – 心跳時間間隔

MQTT服務端運行過程中,當有客户端因為某種原因斷開了與服務端的連接,服務端需要實時瞭解這一情況。KeepAlive正是用於服務端了解客户端連接情況的。

客户端在沒有向服務端發送信息時,可以定時向服務端發送一條消息。這條用於心跳機制的消息也被稱作心跳請求。

心跳請求的作用正是用於告知服務端,當前客户端依然在線。服務端在收到客户端的心跳請求後,會回覆一條消息。這條回覆消息被稱作心跳響應。 image.png

客户端在心跳間隔時間內,如果有消息發佈,那就直接發佈消息而不發佈心跳請求,但是在心跳間隔時間內,客户端沒有消息發佈,那麼它就會發布一條心跳請求給服務端,這個心跳請求的目的就是為了告訴服務端,我還在線。

五: SUBSCRIBE – 訂閲主題

當客户端連接到服務端後,除了可以發佈消息,也可以接收消息。所有MQTT消息都有主題。客户端要想接收消息,首先要訂閲該消息的主題。這樣,當有客户端向該主題發佈消息後,訂閲了該主題的客户端就能接收到消息了。

客户端要想訂閲主題,首先要向服務端發送主題訂閲請求。客户端是通過向服務端發送SUBSCRIBE報文來實現這一請求的。客户端在訂閲主題時也可以明確QoS。服務端會根據SUBSCRIBE中的QoS來提供相應的服務保證。

「其他文章」