當前位置:首頁 > IT技術(shù) > 其他 > 正文

MQTT 入門(2)--MQTT 發(fā)布訂閱詳解
2022-05-29 22:25:22

本文主要介紹 MQTT 協(xié)議中發(fā)布訂閱的詳細過程。

1、Connect(連接)

MQTT 協(xié)議基于 TCP/IP 協(xié)議,MQTT Broker 和 Client 都有需要有 TCP/IP 地址。Client 連接?MQTT Broker 時有如下相關(guān)配置項:

Client ID

服務端使用 ClientId 識別客戶端。連接服務端的每個客戶端都有唯一的 ClientId ??蛻舳撕头斩硕急仨毷褂?ClientId 識別兩者之間的?MQTT 會話相關(guān)的狀態(tài)。

ClientId 必須存在,但是服務端可以允許客戶端提供一個零字節(jié)的 ClientId,如果這樣做了,服務端必須將這看作特殊情況并分配唯一的 ClientId 給那個客戶端。然后正常處理這個 CONNECT 報文。

Username/Password

MQTT 可以通過發(fā)送用戶名和密碼來進行相關(guān)的認證和授權(quán),但是,如果此信息未加密,則用戶名和密碼是以明文的方式發(fā)送的。

Keep Alive

保持連接(Keep Alive)是一個以秒為單位的時間間隔,它是指在客戶端傳輸完成一個控制報文的時刻到發(fā)送下一個報文的時刻,兩者之間允許空閑的最大時間間隔??蛻舳素撠煴WC控制報文發(fā)送的時間間隔不超過保持連接的值。如果沒有任何其它的控制報文可以發(fā)送,客戶端必須發(fā)送一個 PINGREQ 報文。

如果 Keep Alive 的值非零,并且服務端在一點五倍的 Keep Alive 時間內(nèi)沒有收到客戶端的控制報文,它必須斷開客戶端的網(wǎng)絡連接,認為網(wǎng)絡連接已斷開。

Clean Session

客戶端和服務端可以保存會話狀態(tài),以支持跨網(wǎng)絡連接的可靠消息傳輸,這個標志告訴服務器這次連接是不是一個全新的連接。

客戶端的會話狀態(tài)包括:

  • 已經(jīng)發(fā)送給服務端,但是還沒有完成確認的 QoS 1 和 QoS 2 級別的消息
  • 已從服務端接收,但是還沒有完成確認的 QoS 2 級別的消息。

服務端的會話狀態(tài)包括:

  • 會話是否存在,即使會話狀態(tài)的其它部分都是空。
  • 客戶端的訂閱信息。
  • 已經(jīng)發(fā)送給客戶端,但是還沒有完成確認的 QoS 1 和 QoS 2 級別的消息。
  • 即將傳輸給客戶端的 QoS 1和 QoS 2 級別的消息。
  • 已從客戶端接收,但是還沒有完成確認的 QoS 2 級別的消息。
  • 可選,準備發(fā)送給客戶端的 QoS 0 級別的消息。

如果 CleanSession 標志被設置為 1,客戶端和服務端必須丟棄之前的任何會話并開始一個新的會話。會話僅持續(xù)和網(wǎng)絡連接同樣長的時間。

如果 CleanSession 標志被設置為 0,服務端必須基于當前會話(使用 ClientId 識別)的狀態(tài)恢復與客戶端的通信。如果沒有與這個客戶端標識符關(guān)聯(lián)的會話,服務端必須創(chuàng)建一個新的會話。當連接斷開后,客戶端和服務端必須保存會話信息。

2、Connack(確認連接請求)

客戶端發(fā)送 Connect 報文請求對服務器的連接,服務器必須發(fā)送 Connack 報文作為對 來自客戶端的 Connect 報文的回應。如果客戶端在合理的時間內(nèi)沒有收到服務端的CONNACK報文,客戶端應該關(guān)閉網(wǎng)絡連接。合理的時間取決于應用的類型和通信基礎(chǔ)設施。

Connack 報文包含 Session Present 和 Connect Return code 兩個重要的標志。

Session Present

Session Present 標志表示當前會話是否是一個新的會話,如果服務端收到 CleanSession 標志為1的連接,Connack報文中的 SessionPresent 標志為 0 。如果服務端收到一個 CleanSession 為0的連接,SessionPresent 標志的值取決于服務端是否已經(jīng)保存了 ClientId 對應客戶端的會話狀態(tài)。如果服務端已經(jīng)保存了會話狀態(tài),Connack 報文中的 SessionPresent 標志為 1,如果服務端沒有已保存的會話狀態(tài),Connack 報文中的 SessionPresent 標志為 0.

Connect Return code

Connect Return code 表示服務器對此次 Connect 的回應,0 表示連接已被服務器接受。如果服務端收到一個合法的 CONNECT 報文,但出于某些原因無法處理它,服務端應該嘗試發(fā)送一個包含非零返回碼(表格中的某一個)的 CONNACK 報文。如果服務端發(fā)送了一個包含非零返回碼的CONNACK 報文,那么它必須關(guān)閉網(wǎng)絡連接。

返回碼響應描述
0 0x00連接已接受 連接已被服務端接受
1 0x01連接已拒絕,不支持的協(xié)議版本 服務端不支持客戶端請求的MQTT協(xié)議級別
2 0x02連接已拒絕,不合格的客戶端標識符 客戶端標識符是正確的UTF-8編碼,但服務端不允許使用
3 0x03連接已拒絕,服務端不可用 網(wǎng)絡連接已建立,但MQTT服務不可用
4 0x04連接已拒絕,無效的用戶名或密碼 用戶名或密碼的數(shù)據(jù)格式無效
5 0x05連接已拒絕,未授權(quán) 客戶端未被授權(quán)連接到此服務器
6-255 ? 保留

如果認為上表中的所有連接返回碼都不太合適,那么服務端必須關(guān)閉網(wǎng)絡連接,不需要發(fā)送CONNACK 報文。

3、Subscribe(訂閱主題)

客戶端向服務端發(fā)送 Subscribe 報文用于創(chuàng)建一個或多個訂閱。每個訂閱注冊客戶端關(guān)心的一個或多個主題。為了將應用消息轉(zhuǎn)發(fā)給與那些訂閱匹配的主題,服務端發(fā)送 Publish 報文給客戶端。Subscribe 報文為每個訂閱指定了最大的 QoS 等級,服務端根據(jù)這個發(fā)送應用消息給客戶端。

Subscribe 報文的有效載荷必須包含至少一對主題過濾器 和 QoS 等級字段組合。沒有有效載荷的 Subscribe 報文是違反協(xié)議的。

4、Suback(訂閱確認)

服務端發(fā)送 Suback 報文給客戶端,用于確認它已收到并且正在處理 Subscribe 報文。

Suback 報文包含一個原因碼列表,用于指定授予的最大QoS等級或 Subscribe 報文所請求的每個訂閱發(fā)生的錯誤,每個原因碼對應 Subscribe 報文中的一個主題過濾器。Suback 報文中的原因碼順序必須與 Subscribe 報文中的主題過濾器順序相匹配。

允許的返回碼值:

  • 0x00 - 最大QoS 0
  • 0x01 - 成功 – 最大QoS 1
  • 0x02 - 成功 – 最大 QoS 2
  • 0x80 - Failure 失敗

5、Publish(發(fā)布消息)

Publish 報文是指從客戶端向服務端或者服務端向客戶端傳輸一個應用消息,服務器收到 Publish 報文后根據(jù)主題過濾器將消息轉(zhuǎn)發(fā)給其他客戶端。

發(fā)布消息時有如下配置項:

Topic

主題名(Topic Name)用于識別消息應該被發(fā)布到哪一個會話,服務端發(fā)送給訂閱客戶端的 Publish 報文的主題名必須匹配該訂閱的主題過濾器。

QoS

QoS 表示應用消息分發(fā)的服務質(zhì)量等級保證

QoS值Bit 2Bit 1描述
0 0 0 最多分發(fā)一次
1 0 1 至少分發(fā)一次
2 1 0 只分發(fā)一次
- 1 1 保留位

Publish 報文不能將 QoS 所有的位設置為 1。如果服務端或客戶端收到 QoS 所有位都為 1 的 Publish 報文,它必須關(guān)閉網(wǎng)絡連接。

Retain

如果客戶端發(fā)給服務端的 Publish 報文的保留(RETAIN)標志被設置為 1,服務端必須存儲這個應用消息和它的服務質(zhì)量等級(QoS),以便它可以被分發(fā)給未來的主題名匹配的訂閱者 。一個新的訂閱建立時,對每個匹配的主題名,如果存在最近保留的消息,它必須被發(fā)送給這個訂閱者。如果服務端收到一條保留(RETAIN)標志為1的Q消息,它必須丟棄之前為那個主題保留的任何消息,并將這個新的消息當作那個主題的新保留消息。

保留標志為 1 且有效載荷為零字節(jié)的 Publish 報文會被服務端當作正常消息處理,它會被發(fā)送給訂閱主題匹配的客戶端。此外,同一個主題下任何現(xiàn)存的保留消息必須被移除,因此這個主題之后的任何訂閱者都不會收到保留消息。

服務端發(fā)送 Publish 報文給客戶端時,如果消息是作為客戶端一個新訂閱的結(jié)果發(fā)送,它必須將報文的保留標志設為 1。當一個 Publish 報文發(fā)送給客戶端是因為匹配一個已建立的訂閱時,服務端必須將保留標志設為 0,不管它收到的這個消息中保留標志的值是多少。

如果客戶端發(fā)給服務端的 Publish 報文的保留標志位 0,服務端不能存儲這個消息也不能移除或替換任何現(xiàn)存的保留消息。

Payload

有效載荷包含將被發(fā)布的應用消息。數(shù)據(jù)的內(nèi)容和格式是應用特定的,可以發(fā)送圖像,任何編碼的文本,加密的數(shù)據(jù)以及幾乎所有二進制數(shù)據(jù)。

?

?

參考:https://www.emqx.com/zh/blog/how-to-use-mqtt-packet-to-implement-publishing-and-subscribing-functions

本文摘自 :https://www.cnblogs.com/

開通會員,享受整站包年服務立即開通 >