物聯(lián)網(wǎng)核心協(xié)議MQTT快速入門1簡(jiǎn)介

想象一下,我們有幾十個(gè)不同的設(shè)備,它們之間必須交換數(shù)據(jù)。

這些設(shè)備是物聯(lián)網(wǎng)(IoT)板,上面連接了幾十個(gè)傳感器。我們有以下具有不同處理能力的物聯(lián)網(wǎng)板。Raspberry Pi 3, Raspberry Pi Model B, Intel Edison, and Intel Joule 570x. 這些板子中的每一塊都要能夠發(fā)送和接收數(shù)據(jù)。此外,我們希望許多移動(dòng)設(shè)備能夠發(fā)送和接收數(shù)據(jù),其中一些設(shè)備運(yùn)行iOS,另一些運(yùn)行Android。我們必須與許多編程語(yǔ)言合作。

我們的無線網(wǎng)絡(luò)有些不可靠,我們有一些高延遲的環(huán)境。有些設(shè)備的功率比較低,很多設(shè)備都是靠電池供電,資源比較匱乏。此外,我們還要注意網(wǎng)絡(luò)帶寬的使用。

我們可以使用HTTP請(qǐng)求,并建立一個(gè)發(fā)布-訂閱模型來交換不同設(shè)備之間的數(shù)據(jù)。然而,有一種協(xié)議是專門設(shè)計(jì)的,它比HTTP 1.1協(xié)議更輕巧,在涉及到不可靠的網(wǎng)絡(luò)和連接斷斷續(xù)續(xù)的情況下,它能更好地工作。MQ Telemetry Transport( MQTT )更適合這種情況,在這種情況下,許多設(shè)備之間必須通過互聯(lián)網(wǎng)近乎實(shí)時(shí)地交換數(shù)據(jù),而我們需要消耗盡可能少的網(wǎng)絡(luò)帶寬。

MQTT協(xié)議是一種機(jī)器對(duì)機(jī)器(M2M Machine-to-Machine)及物聯(lián)網(wǎng)連接協(xié)議。MQTT是一個(gè)輕量級(jí)的消息傳遞協(xié)議,它使用基于broker的發(fā)布訂閱機(jī)制。

了解MQTT協(xié)議的便捷場(chǎng)景

MQTT適用于以下需要進(jìn)行數(shù)據(jù)交換的應(yīng)用領(lǐng)域。

  • 資產(chǎn)跟蹤和管理
  • 汽車遠(yuǎn)程信息處理技術(shù)
  • 化學(xué)檢測(cè)
  • 環(huán)境和交通監(jiān)測(cè)
  • 野戰(zhàn)部隊(duì)自動(dòng)化
  • 火災(zāi)和氣體測(cè)試
  • 家庭自動(dòng)化
  • 車載信息娛樂系統(tǒng) (IVI In-Vehicle Infotainment)
  • 醫(yī)學(xué)
  • 訊息傳遞
  • 銷售點(diǎn)(POS Point of Sale)亭
  • 鐵路
  • 無線電頻率識(shí)別(RFID Radio-Frequency Identification)
  • 監(jiān)視控制和數(shù)據(jù)采集(SCADA Supervisory Control and Data Acquisition)
  • 老虎機(jī)

綜上所述,MQTT被設(shè)計(jì)成適合支持物聯(lián)網(wǎng)、M2M、嵌入式和移動(dòng)應(yīng)用中的以下典型挑戰(zhàn)。

  • 輕量
  • 以最小的數(shù)據(jù)包分發(fā)大量的數(shù)據(jù)。
  • 支持面向事件的范式,異步雙向低延遲推送消息。
  • 輕松地將數(shù)據(jù)從一個(gè)客戶端發(fā)送至多個(gè)客戶端。
  • 只要事件發(fā)生,就可以監(jiān)聽(面向事件的架構(gòu))。
  • 支持一直連接和有時(shí)連接的模式。
  • 在不可靠的網(wǎng)絡(luò)上發(fā)布信息,并在脆弱的連接上提供可靠的傳輸。
  • 與電池供電的設(shè)備或需要低功率消耗的設(shè)備配合得非常好。
  • 能夠?qū)崿F(xiàn)近乎實(shí)時(shí)的信息傳遞。
  • 數(shù)據(jù)安全和隱私
  • 可擴(kuò)展,將數(shù)據(jù)分發(fā)到幾十萬個(gè)客戶。

使用發(fā)布-訂閱模式

在深入了解MQTT之前,我們必須先了解發(fā)布-訂閱模式,也就是pub-sub模式。在publish-sub模式中,發(fā)布消息的客戶端與接收消息的其他客戶端是解耦的??蛻舳瞬恢榔渌蛻舳说拇嬖???蛻舳丝梢园l(fā)布特定類型的消息,只有對(duì)特定類型的消息感興趣的客戶端才會(huì)收到發(fā)布的消息。

發(fā)布-訂閱模式需要一個(gè)代理,也就是服務(wù)器。所有的客戶端都與broker建立連接。通過broker發(fā)送消息的客戶端被稱為發(fā)布者。broker對(duì)接收到的消息進(jìn)行過濾,并將其分發(fā)到對(duì)接收到的消息類型感興趣的客戶端。對(duì)特定類型的消息感興趣的客戶向經(jīng)紀(jì)人注冊(cè)的客戶被稱為訂閱者。因此,發(fā)布者和訂閱者都與經(jīng)紀(jì)人建立了聯(lián)系。

消息過濾的工作

broker必須確保訂閱者只收到他們感興趣的消息。在發(fā)布-訂閱模式中,可以根據(jù)不同的標(biāo)準(zhǔn)來過濾消息。我們將重點(diǎn)分析基于話題的過濾 ,也稱為基于主題的過濾。

考慮到每條消息都屬于一個(gè)主題。當(dāng)發(fā)布者請(qǐng)求broker發(fā)布消息時(shí),必須同時(shí)指定主題和消息。經(jīng)紀(jì)人接收到消息后,將其傳遞給所有訂閱了該消息所屬主題的訂閱者。

經(jīng)紀(jì)人不需要檢查消息的有效載荷就可以將消息傳遞給相應(yīng)的訂閱者,它只需要檢查每一條已經(jīng)到達(dá)并需要過濾的消息的主題,然后再發(fā)布給相應(yīng)的訂閱者。

Raspberry Pi 3板子發(fā)布一條消息,以120英尺作為有效載荷,以sensor1/altitude作為主題。發(fā)布者,將發(fā)布請(qǐng)求發(fā)送給broker。broker將消息分發(fā)到訂閱sensor1/altitude主題的兩個(gè)客戶端:iOS智能手機(jī)和Android平板電腦。

英特爾愛迪生板塊發(fā)布一條消息,以75 F作為有效載荷,以sensor42/temperature作為主題。發(fā)布者將發(fā)布請(qǐng)求發(fā)送給經(jīng)紀(jì)人。經(jīng)紀(jì)人將消息發(fā)布給唯一訂閱sensor42/temperature主題的客戶端:Android平板電腦。這樣,Android平板電腦就會(huì)收到兩條消息。

客戶端、服務(wù)器和連接。

MQTT broker被稱為MQTT服務(wù)器。MQTT客戶端可以同時(shí)是發(fā)布者和訂閱者,也就是說,客戶端可以向特定的主題發(fā)布消息,也可以接收屬于客戶端訂閱的主題的消息。

任何擁有TCP/IP協(xié)議棧并能夠使用MQTT庫(kù)的設(shè)備都可以成為MQTT客戶端,即成為發(fā)布者、訂閱者或既是發(fā)布者又是訂閱者。

有許多MQTT服務(wù)器可用于最流行的平臺(tái),包括Linux、Windows和macOS。我們將使用Eclipse Mosquitto MQTT服務(wù)器(http://www.mosquitto.org)。Mosquitto是一個(gè)開源的MQTT服務(wù)器,具有EPL/EDL許可證,與MQTT 5.0、3.1和3.1.1版本兼容。其他服務(wù)器有Erlang MQTT Broker(EMQ),也就是EMQTT (http://www.emqtt.io),以及HiveMQ(http://hivemq.com)等。此外有基于云的MQTT服務(wù)器合作,如CloudMQTT(http://www.cloudmqtt.com)。

MQTT服務(wù)器是我們之前分析的發(fā)布/訂閱模型的中心樞紐。MQTT服務(wù)器負(fù)責(zé)對(duì)MQTT客戶端進(jìn)行認(rèn)證和授權(quán),客戶端經(jīng)過認(rèn)證和授權(quán)后就可以成為發(fā)布者和/或訂閱者。所以,MQTT客戶端首先要做的就是與MQTT服務(wù)器建立連接。

為了建立連接,MQTT客戶端必須向MQTT服務(wù)器發(fā)送一個(gè)CONNECT控制包,該控制包的有效載荷必須包括所有必要的信息,以啟動(dòng)連接并進(jìn)行認(rèn)證和授權(quán)。MQTT服務(wù)器會(huì)檢查CONNECT包,進(jìn)行認(rèn)證和授權(quán),并向客戶端發(fā)送一個(gè)CONNACK控制包的響應(yīng),我們了解CONNECT控制包后再詳細(xì)分析。如果MQTT客戶端發(fā)送無效的CONNECT控制包,服務(wù)器會(huì)自動(dòng)關(guān)閉連接。

在MQTT客戶端和MQTT服務(wù)器之間建立了成功的連接后,服務(wù)器將保持連接的開放性,直到客戶端失去連接或向服務(wù)器發(fā)送DISCONNECT控制包來關(guān)閉連接。

CONNECT控制包必須在有效載荷中包含以下字段的值,以及控制包中包含的特殊標(biāo)志字節(jié)的位。我們要了解這些字段和標(biāo)志的含義,因?yàn)楫?dāng)我們使用MQTT工具和MQTT客戶端庫(kù)時(shí),我們將能夠指定它們的值。

ClientId : 客戶端標(biāo)識(shí)符,也稱為客戶端ID,是一個(gè)字符串,用于標(biāo)識(shí)每個(gè)連接到MQTT服務(wù)器的MQTT客戶端。每個(gè)連接到MQTT服務(wù)器的客戶端必須有一個(gè)唯一的ClientId,服務(wù)器使用它來標(biāo)識(shí)它所持有的與客戶端和服務(wù)器之間的MQTT會(huì)話有關(guān)的狀態(tài)。如果客戶端指定一個(gè)空值作為ClientId ,MQTT服務(wù)器必須生成一個(gè)唯一的ClientId來識(shí)別客戶端。然而,這種行為取決于為CleanSession字段指定的值。

CleanSession : 清潔會(huì)話標(biāo)志是一個(gè)布爾值,它指定了MQTT客戶端從MQTT服務(wù)器斷開連接后再重新連接的情況。如果CleanSession被設(shè)置為1或true,客戶端就會(huì)向MQTT服務(wù)器表明,只要網(wǎng)絡(luò)連接還在,會(huì)話就會(huì)持續(xù)。在MQTT客戶端斷開與MQTT服務(wù)器的連接后,任何與該會(huì)話相關(guān)的信息都會(huì)被丟棄。從同一個(gè)MQTT客戶端到MQTT服務(wù)器的新連接將不會(huì)使用前一個(gè)會(huì)話的數(shù)據(jù),而是一個(gè)新的清潔會(huì)話。如果CleanSession被設(shè)置為0或false,我們將使用一個(gè)持久的會(huì)話。在這種情況下,MQTT服務(wù)器會(huì)存儲(chǔ)MQTT客戶端的所有訂閱,當(dāng)MQTT客戶端斷開連接時(shí),MQTT服務(wù)器會(huì)存儲(chǔ)所有到達(dá)的消息,這些消息具有特定的服務(wù)質(zhì)量級(jí)別,與MQTT客戶端在斷開連接時(shí)的訂閱相匹配。這樣一來,當(dāng)同一個(gè)MQTT客戶端與MQTT服務(wù)器建立新的連接時(shí),MQTT客戶端將擁有相同的訂閱,并將接收到失去連接時(shí)無法接收的所有消息。我們將在后面深入探討消息的服務(wù)質(zhì)量等級(jí)以及它們與clean session標(biāo)志或persistent session選項(xiàng)的關(guān)系。

當(dāng)clean session標(biāo)志被設(shè)置為0或false時(shí),客戶端向服務(wù)器表明它想要一個(gè)持久會(huì)話。我們只需要記住一個(gè)干凈的會(huì)話和一個(gè)持久的會(huì)話是相反的。

UserName : 如果客戶端想要指定一個(gè)用戶名來向MQTT服務(wù)器請(qǐng)求認(rèn)證和授權(quán),它必須將UserName標(biāo)志設(shè)置為1或true,并為UserName字段指定一個(gè)值。

password : 如果客戶端要指定密碼來請(qǐng)求 MQTT 服務(wù)器進(jìn)行身份驗(yàn)證和授權(quán),則必須將 Password 標(biāo)志設(shè)置為 1 或 true,并為 Password 字段指定一個(gè)值。

ProtocolLevel : 協(xié)議級(jí)別值表示MQTT客戶端請(qǐng)求MQTT服務(wù)器使用的MQTT協(xié)議版本。

KeepAlive : KeepAlive是一個(gè)以秒為單位的時(shí)間間隔。如果keep alive的值不等于0,MQTT客戶端會(huì)在KeepAlive指定的時(shí)間內(nèi)向服務(wù)器發(fā)送控制包。如果MQTT客戶端不需要發(fā)送任何控制包,它必須向MQTT服務(wù)器發(fā)送一個(gè)PINGREQ控制包,也就是一個(gè)ping請(qǐng)求來告訴MQTT服務(wù)器客戶端連接是活著的。MQTT服務(wù)器響應(yīng)PINGREQ控制包,向MQTT客戶端發(fā)出PINGRESP響應(yīng),即ping響應(yīng),告訴MQTT客戶端與MQTT服務(wù)器的連接是活的。當(dāng)沒有任何這些控制包時(shí),連接就會(huì)被關(guān)閉。如果keep alive的值為0 ,則關(guān)閉keep alive機(jī)制。

Will , WillQoS , WillRetain , WillTopic 和 WillMessage : 這些標(biāo)志和字段允許 MQTT 客戶端利用 MQTT 的遺囑功能。如果 MQTT 客戶端將 Will 標(biāo)志設(shè)置為 1 或 true,則表明它希望 MQTT 服務(wù)器存儲(chǔ)與會(huì)話相關(guān)聯(lián)的遺囑信息。WillQoS標(biāo)志指定了最后一條WillMessage所需的服務(wù)質(zhì)量,WillRetain標(biāo)志則表示該messsage在發(fā)布時(shí)是否必須保留。如果MQTT客戶端將Will標(biāo)志設(shè)置為1或true,它必須在WillTopic和WillMessage字段中指定WillMessage的主題和消息。如果MQTT客戶端斷開或失去與MQTT服務(wù)器的連接,MQTT服務(wù)器將把WillMessage字段中指定的消息發(fā)布到WillTopic字段中指定的主題,并選擇服務(wù)質(zhì)量。我們將在后面詳細(xì)分析這個(gè)功能。

MQTT服務(wù)器將處理一個(gè)有效的CONNECT控制數(shù)據(jù)包,并將以CONNACK控制數(shù)據(jù)包作出響應(yīng)。這個(gè)控制包將包括以下標(biāo)志的值,包含在頭中。我們要了解這些標(biāo)志的含義,因?yàn)楫?dāng)我們使用MQTT工具和MQTT客戶端庫(kù)時(shí),我們將能夠檢索到它們的值。

SessionPresent : 如果MQTT服務(wù)器收到的連接請(qǐng)求的CleanSession標(biāo)志設(shè)置為1或true,那么SessionPresent標(biāo)志的值將為0或false,因?yàn)闆]有存儲(chǔ)的會(huì)話將被重新使用。如果在連接請(qǐng)求中CleanSession標(biāo)志被設(shè)置為0或false,那么MQTT服務(wù)器將使用一個(gè)持久會(huì)話,如果服務(wù)器在之前的連接中為客戶端設(shè)置了一個(gè)持久會(huì)話并將其找回,那么SessionPresent標(biāo)志的值將為1或true。否則,SessionPresent將為0或false。想要使用持久化會(huì)話的MQTT客戶端可以使用這個(gè)標(biāo)志的值來決定它是否需要請(qǐng)求訂閱所需的主題,或者訂閱是否已經(jīng)從持久化會(huì)話中恢復(fù)。

ReturnCode 。如果授權(quán)和認(rèn)證通過,連接成功建立,ReturnCode的值將為0。否則,返回代碼將不同于0,客戶端和服務(wù)器之間的網(wǎng)絡(luò)連接將被關(guān)閉。下表顯示了ReturnCode的可能值及其含義。

返回碼的值

0 連接被接受

1 連接被拒絕,因?yàn)镸QTT服務(wù)器不支持MQTT客戶端在CONNECT控制包中要求的MQTT協(xié)議版本。

2 連接被拒絕,因?yàn)橹付ǖ腃lientId(客戶標(biāo)識(shí)符)已被拒絕。

3 連接被拒絕,因?yàn)榫W(wǎng)絡(luò)連接已經(jīng)建立,但MQTT服務(wù)不可用。

4 由于用戶名或密碼值不正確,連接被拒絕。

5 由于授權(quán)失敗,連接被拒絕

?著作權(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)容