淺談,實(shí)例mqtt;

簡(jiǎn)介

MQTT 全稱為 Message Queuing Telemetry Transport(消息隊(duì)列遙測(cè)傳輸)是一種基于發(fā)布/訂閱范式的“輕量級(jí)”消息協(xié)議,由 IBM 發(fā)布。

  • MQTT 可以被解釋為一種低開銷,低帶寬占用的即時(shí)通訊協(xié)議,可以用極少的代碼和帶寬的為連接遠(yuǎn)程設(shè)備提供實(shí)時(shí)可靠的消息服務(wù),它適用于硬件性能低下的遠(yuǎn)程設(shè)備以及網(wǎng)絡(luò)狀況糟糕的環(huán)境下,因此 MQTT 協(xié)議在 IoT(Internet of things,物聯(lián)網(wǎng)),小型設(shè)備應(yīng)用,移動(dòng)應(yīng)用等方面有較廣泛的應(yīng)用。
  • IoT 設(shè)備要運(yùn)作,就必須連接到互聯(lián)網(wǎng),設(shè)備才能相互協(xié)作,以及與后端服務(wù)協(xié)同工作。而互聯(lián)網(wǎng)的基礎(chǔ)網(wǎng)絡(luò)協(xié)議是 TCP/IP,MQTT 協(xié)議是基于 TCP/IP 協(xié)議棧而構(gòu)建的,因此它已經(jīng)慢慢的已經(jīng)成為了 IoT 通訊的標(biāo)準(zhǔn)。

在簡(jiǎn)介完 MQTT 協(xié)議后,EMQ君將從其一些基本特點(diǎn)和基本概念為兩部分,介紹 MQTT 協(xié)議。

基本特點(diǎn)

  1. MQTT是一種發(fā)布/訂閱傳輸協(xié)議,基本原理和實(shí)現(xiàn)如下;
image

MQTT 協(xié)議提供一對(duì)多的消息發(fā)布,可以解除應(yīng)用程序耦合,信息冗余小。該協(xié)議需要客戶端和服務(wù)端,而協(xié)議中主要有三種身份:發(fā)布者(Publisher)、代理(Broker,服務(wù)器)、訂閱者(Subscriber)。其中,消息的發(fā)布者和訂閱者都是客戶端,消息代理是服務(wù)器,而消息發(fā)布者可以同時(shí)是訂閱者,實(shí)現(xiàn)了生產(chǎn)者與消費(fèi)者的脫耦。

  1. 使用 TCP/IP 提供網(wǎng)絡(luò)連接,提供有序、無(wú)損、雙向連接;

    MQTT 是一種連接協(xié)議,它指定了如何組織數(shù)據(jù)字節(jié)并通過(guò) TCP/IP 網(wǎng)絡(luò)傳輸它們。設(shè)備聯(lián)網(wǎng),也需要連接到互聯(lián)網(wǎng)中,在大萬(wàn)維的世界中,TCP 如同汽車,有輪子就能用來(lái)運(yùn)輸數(shù)據(jù),MQTT 就像是交通規(guī)則。在網(wǎng)絡(luò)模型中,TCP是傳輸層協(xié)議,而 MQTT是在應(yīng)用層,在 TCP 的上層,因此MQTT 也是基于這個(gè)而構(gòu)建的,提高了可靠性。

  2. 對(duì)負(fù)載內(nèi)容屏蔽的消息傳輸;

    可以對(duì)消息訂閱者所接受到的內(nèi)容有所屏蔽。

  3. 具體有三種消息發(fā)布的服務(wù)質(zhì)量:

    • 至多一次,消息發(fā)布完全依賴底層 TCP/IP 網(wǎng)絡(luò)。會(huì)發(fā)生消息丟失或重復(fù)。這一級(jí)別可用于如下情況,環(huán)境傳感器數(shù)據(jù),丟失一次讀記錄無(wú)所謂,因?yàn)椴痪煤筮€會(huì)有第二次發(fā)送。
    • 至少一次,確保消息到達(dá),但消息重復(fù)可能會(huì)發(fā)生。
    • 只有一次,確保消息到達(dá)一次。這一級(jí)別可用于如下情況,在計(jì)費(fèi)系統(tǒng)中,消息重復(fù)或丟失會(huì)導(dǎo)致不正確的結(jié)果。
  4. 小型傳輸,開銷小,固定長(zhǎng)度的頭部是 2 字節(jié),協(xié)議交換最小化,以降低網(wǎng)絡(luò)流量;

    整體上協(xié)議可拆分為:固定頭部+可變頭部+消息體,這就是為什么在介紹里說(shuō)它非常適合"在物聯(lián)網(wǎng)領(lǐng)域,傳感器與服務(wù)器的通信,信息的收集"。

  5. 使用Last Will和Testament特性通知有關(guān)各方客戶端異常中斷的機(jī)制;

    Last Will:即遺言機(jī)制,用于通知同一主題下的其他設(shè)備發(fā)送遺言的設(shè)備已經(jīng)斷開了連接。

    Testament:遺囑機(jī)制,功能類似于Last Will。

基本概念

  1. MQTT 客戶端

    一個(gè)使用 MQTT 協(xié)議的設(shè)備、應(yīng)用程序等,它總是建立到服務(wù)器的網(wǎng)絡(luò)連接。

    • 可以發(fā)布信息,其他客戶端可以訂閱該信息

    • 訂閱其它客戶端發(fā)布的消息

    • 退訂或刪除應(yīng)用程序的消息

    • 斷開與服務(wù)器連接

  2. MQTT 服務(wù)器

    MQTT 服務(wù)器以稱為 Broker(消息代理),以是一個(gè)應(yīng)用程序或一臺(tái)設(shè)備。它是位于消息發(fā)布者 和訂閱者之間

    • 接受來(lái)自客戶端的網(wǎng)絡(luò)連接
    • 接受客戶端發(fā)布的應(yīng)用信息
    • 處理來(lái)自客戶端的訂閱和退訂請(qǐng)求
    • 向訂閱的客戶轉(zhuǎn)發(fā)應(yīng)用程序消息
  3. 主題(Topic)

    連接到一個(gè)應(yīng)用程序消息的標(biāo)簽,該標(biāo)簽與服務(wù)器的訂閱相匹配。服務(wù)器會(huì)將消息發(fā)送給訂閱所匹配標(biāo)簽的每個(gè)客戶端。

    • 要訂閱的主題。一個(gè)主題可以有多個(gè)級(jí)別,級(jí)別之間用斜杠字符分隔。例如,/worldemq/emqtt/emqx 是有效的主題。

    • 訂閱者的Topic name支持通配符#和+ :

      • 支持一個(gè)主題內(nèi)任意級(jí)別話題

      • +只匹配一個(gè)主題級(jí)別的通配符
    • 客戶端成功訂閱某個(gè)主題后,代理會(huì)返回一條 SUBACK 消息,其中包含一個(gè)或多個(gè) returnCode 參數(shù)

  4. 主題篩選器(Topic Filter)

    一個(gè)對(duì)主題名通配符篩選器,在訂閱表達(dá)式中使用,表示訂閱所匹配到的多個(gè)主題。

  5. QoS(消息傳遞的服務(wù)質(zhì)量水平)

    服務(wù)質(zhì)量,標(biāo)志表明此主題范圍內(nèi)的消息傳送到客戶端所需的一致程度。

    • 值 0:不可靠,消息基本上僅傳送一次,如果當(dāng)時(shí)客戶端不可用,則會(huì)丟失該消息。
    • 值 1:消息應(yīng)傳送至少 1 次。
    • 值 2:消息僅傳送一次。
  6. 會(huì)話(Session)

    每個(gè)客戶端與服務(wù)器建立連接后就是一個(gè)會(huì)話,客戶端和服務(wù)器之間有狀態(tài)交互。會(huì)話存在于一個(gè)網(wǎng)絡(luò)之間,也可能在客戶端和服務(wù)器之間跨越多個(gè)連續(xù)的網(wǎng)絡(luò)連接。

  7. 訂閱(Subscription)

    訂閱包含主題篩選器(Topic Filter)和最大服務(wù)質(zhì)量(QoS)。訂閱會(huì)與一個(gè)會(huì)話(Session)關(guān)聯(lián)。一個(gè)會(huì)話可以包含多個(gè)訂閱。每一個(gè)會(huì)話中的每個(gè)訂閱都有一個(gè)不同的主題篩選器。

    • 客戶端在成功建立TCP連接之后,發(fā)送CONNECT消息,在得到服務(wù)器端授權(quán)允許建立彼此連接的CONNACK消息之后,客戶端會(huì)發(fā)送SUBSCRIBE消息,訂閱感興趣的Topic主題列表(至少一個(gè)主題)
    • 訂閱的主題名稱采用UTF-8編碼,然后緊跟著對(duì)應(yīng)的QoS值
  8. 發(fā)布(publish)

    控制報(bào)文是指從客戶端向服務(wù)端或者服務(wù)端向客戶端傳輸一個(gè)應(yīng)用消息,MQTT 客戶端發(fā)送消息請(qǐng)求,發(fā)送完成后返回應(yīng)用程序線程

    • 比如安卓的推送服務(wù),還有一些即時(shí)通信軟件如微信等也是采用的推送技術(shù)。
  9. 負(fù)載(Payload)

    消息訂閱者所具體接收的內(nèi)容

簡(jiǎn)單示例

MQTT 協(xié)議主要是根據(jù)以下情況設(shè)計(jì)的:

  • M2M(Machine to Machine),機(jī)器或設(shè)備間端到端通信,比如傳感器之間的數(shù)據(jù)通訊。
  • 設(shè)備(Machine)中,例如傳感器,硬件能力很弱,協(xié)議要考慮盡量小的資源消耗,比如計(jì)算能力和存儲(chǔ)等。

根據(jù) MQTT 的基礎(chǔ)了解后并結(jié)合簡(jiǎn)單的架構(gòu),在這里做一個(gè)簡(jiǎn)單的示例圖,可以更直觀的理解MQTT協(xié)議的通信模型。MQTT Broker 就選擇 EMQ 作為示范。比如有1個(gè)溫度傳感器(1個(gè)Machine),1個(gè)移動(dòng)設(shè)備,1個(gè)電腦,一個(gè)服務(wù)器(3個(gè)Machine),都可以得到或者顯示溫度傳感器的溫度值,需要先通過(guò) MQTT 協(xié)議subscribe(訂閱)一個(gè)比如叫 temperature 的 topic(主題)如下:

image

圖中移動(dòng)設(shè)備,服務(wù)器,電腦需要先通過(guò) EMQ subscribe 一個(gè)叫 temperature 的 topic,當(dāng)溫度傳感器 publish 溫度數(shù)據(jù),三個(gè)設(shè)備就可以收到了。

進(jìn)一步了解MQTT 3

MQTT 3 (當(dāng)前版本3.1.1)是目前使用的最為廣泛的MQTT協(xié)議標(biāo)準(zhǔn)。盡管MQTT5標(biāo)準(zhǔn)已經(jīng)發(fā)布,并且?guī)?lái)了一些令人振奮的新特性,但是在整個(gè)應(yīng)用場(chǎng)景上,從后臺(tái)服務(wù)到消息中間件再到客戶端SDK等環(huán)節(jié)上的產(chǎn)品升級(jí)并沒(méi)有都完成,再加上既有部署的維護(hù),業(yè)界從版本3到5的過(guò)渡可能會(huì)持續(xù)相當(dāng)長(zhǎng)一段時(shí)間,所以,對(duì)于剛加入物聯(lián)網(wǎng)行業(yè)的生力軍來(lái)說(shuō),現(xiàn)在來(lái)學(xué)習(xí)MQTT 3依然是一件很有意義的事情。

MQTT協(xié)議的工作方式

前面簡(jiǎn)介中講到,在一個(gè)QMTT協(xié)議中有三個(gè)角色會(huì)參與到整個(gè)通信過(guò)程,發(fā)布者(publisher)、代理(broker)和訂閱者(subscriber)。有別于傳統(tǒng)的客戶端/服務(wù)器通訊協(xié)議,MQTT協(xié)議并不是端到端的,消息傳遞通過(guò)代理,包括會(huì)話(session)也不是建立在發(fā)布者和訂閱者之間,而是建立在端和代理之間。代理解除了發(fā)布者和訂閱者之間的耦合。

除了發(fā)布者和訂閱者之間傳遞普通消息,代理還可以為發(fā)布者處理保留消息和遺愿消息,并可以更改服務(wù)質(zhì)量(QoS)等級(jí)。

MQTT控制報(bào)文

MQTT協(xié)議工作在TCP之上,端和代理之間通過(guò)交換預(yù)先定義的控制報(bào)文來(lái)完成通信。MQTT報(bào)文有3個(gè)部分組成,并按下表順序出現(xiàn):

固定報(bào)頭(fixed header) 可變報(bào)頭(variable header) 荷載(payload)
所有報(bào)文都包含 部分報(bào)文包含 部分報(bào)文包含

所有的MQTT控制報(bào)文都有一個(gè)固定報(bào)頭,期格式如下:

image

協(xié)議版本3定義了14種MQTT報(bào)文,用于建立/斷開連接、發(fā)布消息、訂閱消息和維護(hù)連接。固定報(bào)頭的第一字節(jié)的4-7位的值指定了報(bào)文類型,其取值如下表。0和15為系統(tǒng)保留值;0-3位為標(biāo)志位,依照?qǐng)?bào)文類型有不同的含義,事實(shí)上,除了PUBLISH報(bào)文以外,其他報(bào)文的標(biāo)志位均為系統(tǒng)保留。如果收到報(bào)文的標(biāo)志位無(wú)效,代理應(yīng)斷開連接。

報(bào)文類型 描述
CONNECT 1 客戶端向代理發(fā)起連接請(qǐng)求
CONNACK 2 連接確認(rèn)
PUBLISH 3 發(fā)布消息
PUBACK 4 發(fā)布確認(rèn)
PUBREC 5 發(fā)布收到(QoS2)
PUBREL 6 發(fā)布釋放(QoS2)
PUBCOMP 7 發(fā)布完成(QoS2)
SUBSCRIBE 8 客戶端向代理發(fā)起訂閱請(qǐng)求
SUBACK 9 訂閱確認(rèn)
UNSUBSCRIBE 10 取消訂閱
UNSUBACK 11 取消訂閱確認(rèn)
PINGREQ 12 PING請(qǐng)求
PINGRESP 13 PING響應(yīng)
DISCONNECT 14 斷開連接

固定報(bào)頭的第二字節(jié)起表示報(bào)文的剩余長(zhǎng)度。最大4個(gè)字節(jié),每字節(jié)可以編碼至127,并含有一位繼續(xù)位,如繼續(xù)位非0,則下一字節(jié)依然為剩余長(zhǎng)度。由此,理論上一個(gè)控制報(bào)文最長(zhǎng)可以到256MB。

一些報(bào)文在固定報(bào)頭和荷載之間可以有一個(gè)可變報(bào)頭。可變報(bào)頭的內(nèi)容根據(jù)報(bào)文類型不同而不同。最常見的可變報(bào)頭是報(bào)文標(biāo)識(shí)符(PacketIdentifier)。

一些報(bào)文可以在最后攜帶一個(gè)荷載。不同的報(bào)文可以無(wú)荷載,可選荷載,或必須帶有荷載。

限于篇幅,在這里我們僅以CONNECT和CONNACK為例解釋一下MQTT報(bào)文的構(gòu)成和報(bào)文響應(yīng)行為。其他報(bào)文請(qǐng)查閱MQTT標(biāo)準(zhǔn)文檔。

CONNECT報(bào)文

限于篇幅,在這里我們僅以CONNECT為例解釋一下MQTT報(bào)文的構(gòu)成。其他報(bào)文請(qǐng)查閱MQTT標(biāo)準(zhǔn)文檔。
CONNECT是客戶端連接到代理的第一個(gè)報(bào)文,如果在連接已經(jīng)存在,代理收到該報(bào)文將會(huì)斷開現(xiàn)有連接。

CONNECT報(bào)文的固定報(bào)頭

image

CONNECT報(bào)文的可變報(bào)頭

CONNECT報(bào)文的可變報(bào)頭由4部分組成:

  • 協(xié)議名。協(xié)議名是UTF-8編碼的大寫的MQTT。
  • 協(xié)議級(jí)別。MQTT 3.1.1的協(xié)議級(jí)別為4.
  • 連接標(biāo)志位。定義連接行為的參數(shù)。見下表。
  • Keep Alive。2字節(jié),客戶端和代理之間的無(wú)活動(dòng)時(shí)間超過(guò)該值后,應(yīng)關(guān)閉連接。如果該值置0表示客戶端不要求代理啟用KEEPALIVE功能。

連接標(biāo)志位:

7 6 5 4 3 2 1 0
用戶名 密碼 保留遺愿 遺愿QoS 遺愿QoS 遺愿 清除會(huì)話 保留(0)

清除會(huì)話標(biāo)志位
這個(gè)標(biāo)志位定義了如何處理會(huì)話狀態(tài)。如果設(shè)置為0,客戶端和代理可以恢復(fù)上一次連接時(shí)的會(huì)話狀態(tài),如果上一次連接的會(huì)話狀態(tài)不存在,代理將會(huì)為客戶端建立一個(gè)新的會(huì)話。如果該位設(shè)置為1,則雙方將清除掉上一次連接的會(huì)話狀態(tài)并建立一個(gè)新的會(huì)話。

遺愿標(biāo)志位
如果遺愿標(biāo)志為1,則遺愿消息會(huì)被存儲(chǔ)在代理上,當(dāng)連接關(guān)閉時(shí),代理將發(fā)布這個(gè)消息,除非在客戶端斷開連接時(shí)把遺愿消息清除了。

遺愿QoS標(biāo)志位
指定了遺愿消息的服務(wù)質(zhì)量等級(jí)。

保留遺愿消息標(biāo)志位
指定在發(fā)布遺愿消息的時(shí)候,是否把該消息作為保留消息存儲(chǔ)在代理。

用戶名標(biāo)志位
如果設(shè)置為1,則用戶名必須出現(xiàn)在荷載中,反之,用戶名不允許出現(xiàn)在荷載中。

密碼標(biāo)志位
如果該位為1,則密碼必須出現(xiàn)在荷載中;如果該位為0,則密碼不允許出現(xiàn)在荷載中。如果用戶名標(biāo)志位為0,則該位必須也為0。

CONNECT報(bào)文的荷載

CONNECT報(bào)文的荷載由一個(gè)或者多個(gè)字段組成,這些字段是否出現(xiàn)由可變報(bào)頭中的標(biāo)志位決定。字段總是以長(zhǎng)度開始。字段出現(xiàn)的順序必須是:客戶端標(biāo)識(shí)符,遺愿主題,遺愿消息,用戶名,密碼。

CONNECT報(bào)文的響應(yīng)

在代理在為MQTT協(xié)議開放的端口上接收到TCP連接請(qǐng)求并建立連接后應(yīng)該會(huì)收到CONNECT報(bào)文,如果在一定時(shí)間內(nèi)代理沒(méi)有收到CONNECT報(bào)文,則應(yīng)該關(guān)閉這個(gè)TCP連接。
在收到CONNECT報(bào)文后,代理應(yīng)該檢查報(bào)文格式是否符合協(xié)議標(biāo)準(zhǔn)。如果不符合協(xié)議標(biāo)準(zhǔn),代理應(yīng)關(guān)閉連接,且不發(fā)送CONNACK報(bào)文給客戶端。
代理可以檢查CONNECT報(bào)文的內(nèi)容并執(zhí)行響應(yīng)的認(rèn)證和鑒權(quán)。如果這些檢查沒(méi)有通過(guò),代理應(yīng)該向客戶端發(fā)送一個(gè)帶有非0返回碼的CONNACK報(bào)文。

CONNACK報(bào)文

CONNACK是代理用來(lái)響應(yīng)客戶端CONNECT的報(bào)文。代理向客戶端發(fā)送的第一個(gè)報(bào)文必須是CONNACT。CONNACK有一個(gè)固定報(bào)頭,一個(gè)可變報(bào)頭,但是不帶有荷載。

CONNACK的固定報(bào)頭

image

CONNACT報(bào)文只有固定報(bào)頭和一個(gè)2字節(jié)的可變報(bào)頭,所以它的剩余長(zhǎng)度總是2。

CONNACK報(bào)文的可變報(bào)頭

CONNACK報(bào)文的可變報(bào)頭為定長(zhǎng)2字節(jié)。第一字節(jié)的0位表示是否有會(huì)話存在。如果代理上已經(jīng)有請(qǐng)求連接的客戶端的會(huì)話,且連接請(qǐng)求的清除會(huì)話標(biāo)識(shí)為0,則該位為1,否則該位為0??蛻舳丝梢愿鶕?jù)這一位的值采取響應(yīng)行為,比如(重新)訂閱主題等。

CONNACK報(bào)文的可變報(bào)頭的第二字節(jié)為返回碼。如果CONNECT請(qǐng)求的格式正確,但是代理依然不能允許客戶端連接,則返回碼為一個(gè)非零值。如果連接成功,則返回0。

返回碼的定義:

返回碼含義
0 成功,連接請(qǐng)求被接受。
1 拒絕連接,不可接受的協(xié)議版本。
2 拒絕連接,不被允許的身份識(shí)別符(Client Identifier)。
3 拒絕連接,服務(wù)器不可用。
4 拒絕連接,無(wú)效的用戶名和密碼。
5 拒絕連接,客戶端無(wú)授權(quán)。
6-255 系統(tǒng)保留。

客戶端接受到代理的CONNACK的返回碼為0,則連接建立完成,雙方可以開始通信。

清除會(huì)話、保留消息和QoS的組合

清除會(huì)話、保留消息等概念,在傳統(tǒng)的客戶端/服務(wù)器方式的通信中不一定會(huì)出現(xiàn),這些概念有時(shí)候不太容易理解,特別是當(dāng)他們被組合起來(lái)用的時(shí)候。

下面的表格匯總了當(dāng)一個(gè)客戶端連接上來(lái)時(shí),它能收到消息的各種情況。

清除會(huì)話位 保留位 訂閱QoS 發(fā)布QoS 可收到的消息
Y N 0 0 N
Y N 0 1 N
Y N 1 0 N
Y N 1 1 N
N N 0 0 N
N N 0 1 N
N N 1 0 N
N N 1 1 Y,會(huì)話全部消息
Y Y 0 0 Y,最后一條消息
Y Y 0 1 Y,最后一條消息
Y Y 1 0 Y,最后一條消息
Y Y 1 1 Y,最后一條消息
N Y 0 0 Y,最后一條消息
N Y 0 1 Y,最后一條消息
N Y 1 0 Y,最后一條消息
N Y 1 1 Y,會(huì)話全部消息

MQTT 5.0 協(xié)議新增介紹

MQTT 5.0 協(xié)議相比 MQTT 3.1.1 協(xié)議新增了許多內(nèi)容, 比如說(shuō)屬性,AUTH 包,還有對(duì)一些字段做了修改,比如將 Clean Session 修改成 Clean Start 配合 Session Expiry Internal 去實(shí)現(xiàn)更靈活的會(huì)話控制。

這里就簡(jiǎn)單羅列一下 5.0 協(xié)議新增的內(nèi)容。

設(shè)計(jì)目標(biāo)

  • 增強(qiáng)了擴(kuò)展性
  • 改善了錯(cuò)誤報(bào)告的方式
  • 定型了一些通用范式,例如能力發(fā)現(xiàn)和請(qǐng)求、響應(yīng)
  • 擴(kuò)展機(jī)制包括用戶屬性(user properties)
  • 性能改善,并且添加了對(duì)小客戶端(small clients) 的支持

讀者可以參考MQTT5.0協(xié)議規(guī)范的附錄C來(lái)了解協(xié)議變更。

屬性

為了達(dá)成新協(xié)議的設(shè)計(jì)目標(biāo),MQTT 5.0 協(xié)議中新增了許多屬性,以下是新添加的屬性列表。

標(biāo)識(shí)符 Identifier(十進(jìn)制) 標(biāo)識(shí)符 Identifier(十六進(jìn)制) 名稱(用法)Name(usage) 類型 Type 報(bào)文/遺囑屬性 Packet/Will Properties
1 0x01 有效載荷格式指示器 Payload Format Indicator 字節(jié) PUBLISH, 遺囑屬性 Will Properties
2 0x02 消息到期間隔 Message Exipiry Interval 四字節(jié)整形 PUBLISH,遺囑屬性
3 0x03 內(nèi)容類型 Content Type UTF-8 編碼字符串 PUBLISH,遺囑屬性
8 0x08 響應(yīng)主題 Response Topic UTF-8 編碼字符串 PUBLISH,遺囑屬性
9 0x09 關(guān)聯(lián)數(shù)據(jù) Correlation Data 二進(jìn)制數(shù)據(jù) Binary Data PUBLISH,遺囑屬性
11 0x0B 訂閱標(biāo)識(shí)符 Subscription Identifier 可變字節(jié)整形 PUBLISH, SUBSCRIBE
17 0x11 會(huì)話到期間隔 Session Expiry Interval 四字節(jié)整形 CONNECT, CONNACK, DISCONNECT
18 0x12 已分配客戶端標(biāo)識(shí)符 Assigned Client Identifier UTF-8 編碼字符串 CONNACK
19 0x13 服務(wù)器?;?Server Keep Alive 兩字節(jié)整形 CONNACK
21 0x15 認(rèn)證方法 Authentication Method UTF-8 編碼字符串 CONNECT, CONNACK, AUTH
22 0x16 認(rèn)證數(shù)據(jù) Authentication Data 二進(jìn)制數(shù)據(jù) CONNECT, CONNACK, AUTH
23 0x17 請(qǐng)求響應(yīng)信息 Request Response Information 字節(jié) CONNECT
24 0x18 遺囑延遲間隔 Will Delay Interval 四字節(jié)整形 遺囑屬性 Will Properties
25 0x19 請(qǐng)求響應(yīng)信息 Request Response Information 字節(jié) CONNECT
26 0x1A 響應(yīng)信息 Response Information UTF-8 編碼字符串 CONNACK, DISCONNECT
28 0x1C 服務(wù)器引用 Server Reference UTF-8 編碼字符串 CONNACK, DISCONNECT
31 0x1F 原因字符串 Reason String UTF-8 編碼字符串 CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK,UNSUBACK, DISCONNECT, AUTH
33 0x21 接收最大值 Receive Maximum 兩字節(jié)整形 CONNECT, CONNACK
34 0x22 主題別名最大值 Topic Alias Maximum 兩字節(jié)整形 CONNECT, CONNACK
35 0x23 主題別名 Topic Alias 兩字節(jié)整形 PUBLISH
36 0x24 服務(wù)質(zhì)量最大值 Maximum QoS 字節(jié) CONNACK
37 0x25 保留可用 Retain Available 字節(jié) CONNACK
38 0x26 用戶屬性 User Property UTF-8 字符串對(duì) UTF-8 String Pair CONNECT, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT, AUTH
39 0x27 最大報(bào)文大小 Maximum Packet Size 四字節(jié)整形 CONNECT, CONNACK
40 0x28 可用通配符訂閱 Wildcard Subscription Available 字節(jié) CONNACK
41 0x29 可用訂閱標(biāo)識(shí)符 Subscription Identifier Available Byte CONNACK
42 0x2A 可用共享訂閱 Shared Subscription Available 字節(jié) CONNACK

原因碼

MQTT v3.1.1 只有寥寥 6 個(gè)返回碼,用來(lái)表示網(wǎng)絡(luò)連接時(shí)可能會(huì)出現(xiàn)的異常行為,在引入屬性后的 MQTT 5.0 協(xié)議中,僅僅這 6 個(gè)返回碼顯然已經(jīng)不足以用來(lái)描述各種異常行為,因此MQTT 5.0 協(xié)議中將返回碼改成了原因碼,用來(lái)實(shí)現(xiàn)改善錯(cuò)誤報(bào)告的目的。

原因碼(十進(jìn)制) 原因碼(十六進(jìn)制) 名稱 報(bào)文
0 0x00 成功 Success CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH
0 0x00 正常斷連 Normal disconnection DISCONNECT
0 0x00 準(zhǔn)許 QoS 0 Granted QoS 0 SUBACK
1 0x01 準(zhǔn)許 QoS 1 Granted QoS 1 SUBACK
2 0x02 準(zhǔn)許 QoS 2 Granted QoS 2 SUBACK
4 0x04 以遺囑消息斷開連接 Disconnect with Will Message DISCONNECT
16 0x10 沒(méi)有匹配的訂閱者 No matching subscribers PUBACK, PUBREC
17 0x11 沒(méi)有訂閱 No subscription existed UNSUBACK
24 0x18 繼續(xù)認(rèn)證 Continue authentication AUTH
25 0x19 重新認(rèn)證 Re-authenticate AUTH
128 0x80 未指定錯(cuò)誤 Unspecified error CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT
129 0x81 畸形報(bào)文 Malformed Packet CONNACK, DISCONNECT
130 0x82 協(xié)議錯(cuò)誤 Protocol Error CONNACK, DISCONNECT
131 0x83 實(shí)現(xiàn)特有錯(cuò)誤 Implementation specific error CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT
132 0x84 不支持的協(xié)議版本 Unsupported Protocol Version CONNACK
133 0x85 客戶端標(biāo)識(shí)符無(wú)效 Client Identifier not valid CONNACK
134 0x86 錯(cuò)誤的用戶名和密碼 Bad User Name or Password CONNACK
135 0x87 未授權(quán) Not authorized CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT
136 0x88 服務(wù)器不可用 Server unavailable CONNACK
137 0x89 服務(wù)器繁忙 Server busy CONNACK, DISCONNECT
138 0x8A 禁止訪問(wèn) Banned CONNACK
139 0x8B 服務(wù)器關(guān)機(jī)中 Server shutting down DISCONNECT
140 0x8C 錯(cuò)誤驗(yàn)證方法 Bad authentication method CONNACK, DISCONNECT
141 0x8D 保活超時(shí) Keep Alive timeout DISCONNECT
142 0x8E 會(huì)話被接管 Session taken over DISCONNECT
143 0x8F 主題過(guò)濾器無(wú)效 Topic Filter invalid SUBACK, UNSUBACK, DISCONNECT
144 0x90 主題名無(wú)效 Topic Name invalid CONNACK, PUBACK, PUBREC, DISCONNECT
145 0x91 報(bào)文標(biāo)識(shí)符在使用中 Packet Identifier in use PUBACK, PUBREC, SUBACK, UNSUBACK=
146 0x92 沒(méi)有發(fā)現(xiàn)報(bào)文標(biāo)識(shí)符 Packet Identifier not found PUBREL, PUBCOMP
147 0x93 超出接收最大值 Receive Maximum exceeded DISCONNECT
148 0x94 主題別名無(wú)效 Topic Alias invalid DISCONNECT
149 0x95 報(bào)文太大 Packet too large CONNACK, DISCONNECT
150 0x96 消息傳輸速率太高 Message rate too high DISCONNECT
151 0x97 超出限額 Quota exceeded CONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT
152 0x98 管理行為 Administrative action DISCONNECT
153 0x99 有效載荷格式無(wú)效 Payload format invalid PUBACK, PUBREC, DISCONNECT
154 0x9A 不支持消息保留 Retain not supported CONNACK, DISCONNECT
155 0x9B 不支持的QoS QoS not supported CONNACK, DISCONNECT
156 0x9C 使用另一臺(tái)服務(wù)器 Use another server CONNACK, DISCONNECT
157 0x9D 服務(wù)器被移除 Server moved CONNACK, DISCONNECT
158 0x9E 不支持的共享訂閱 Shared Subscription not supported SUBACK, DISCONNECT
159 0x9F 超出連接速率 Connection rate exceeded CONNACK, DISCONNECT
160 0xA0 最大連接時(shí)間 Maximum connect time DISCONNECT
161 0xA1 不支持的訂閱標(biāo)識(shí)符 Subscription Identifiers not supported SUBACK, DISCONNECT
162 0xA2 不支持的通配符訂閱 Wildcard Subscription not supported SUBACK, DISCONNECT

實(shí)際應(yīng)用

1. 由于主題別名(Topic Alias)的引入,使 MQTT PUBLISH 控制報(bào)文的體積更小,更便于在帶寬和網(wǎng)絡(luò)受限的物聯(lián)網(wǎng)環(huán)境下傳輸消息。

2. AUTH 包的引入使 MQTT 協(xié)議擴(kuò)展了認(rèn)證方式,增加了詢問(wèn)/響應(yīng)式的認(rèn)證方式,服務(wù)器或客戶端在發(fā)送 CONNECT 與接收 CONNACK 包之間交換 AUTH 報(bào)文來(lái)完成身份驗(yàn)證的流程。

3. 由于很多嵌入式設(shè)備的 CPU 并沒(méi)有對(duì) AES 加密標(biāo)準(zhǔn)下的加密算法提供硬件級(jí)的支持,因此,使用 AES 加密對(duì)嵌入式設(shè)備的硬件開銷是非常大的,所以 MQTT 5.0 協(xié)議提供了新的加密算法 ChaCha20 ,ChaCha20 在軟件層面做加密和解密處理要比 AES 快得多。因此也算是一大進(jìn)步,不過(guò)本人更希望 MQTT 下一版協(xié)議能夠增加對(duì) AEAD 加密算的支持。

總的來(lái)說(shuō),MQTT 5.0 協(xié)議的內(nèi)容增加了很多,協(xié)議書的內(nèi)容幾乎是 MQTT 3.1.1 協(xié)議的兩倍,除了本文上述提到的這些新的變化,還有很多非常細(xì)節(jié)的東西沒(méi)有在這里做詳細(xì)的介紹。基于 MQTT 5.0 協(xié)議現(xiàn)有的很多屬性,在實(shí)現(xiàn) MQTT 5.0 協(xié)議的時(shí)說(shuō)不定還能挖掘出更多的有意思的新用法,不過(guò)這需要開發(fā)人員去多讀協(xié)議的具體細(xì)節(jié),去更深入地理解 MQTT 5.0 協(xié)議。

EMQ作為在github中最流行的MQTT中間件,開始全面支持MQTT 5.0協(xié)議,讀者有興趣的話,趕緊下載試用吧。

下一步

讀完本文之后,不能光做不練啊,想試用一下MQTT嗎?請(qǐng)參考EMQ君的文章常見MQTT服務(wù)器搭建與試用

參考信息

作者:轉(zhuǎn)自 EMQ

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容