<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          關(guān)于MQTT協(xié)議

          共 6274字,需瀏覽 13分鐘

           ·

          2021-03-10 05:43

          最近一段時間亂糟糟的,發(fā)生了好多事情,公眾號也暫停了一段時間,不過嘛,狀態(tài)總要調(diào)整過來的,人嘛,每個月都有那么幾天嘛,所以加油~

          今天我們來講講MQTT,其實對于產(chǎn)品而言,嚴(yán)格來講只要懂得應(yīng)用場景就可以了,但是我依然愿意更深度的去學(xué)習(xí)和分析這些更偏技術(shù)側(cè)的東西,原因也很簡單,不管是MQTT、HTTP還是其他的什么,這些存在了很久且成熟度很高的技術(shù)其實是非常值得借鑒的,他的結(jié)構(gòu)分層,他的運作邏輯,他的異常處理機制都能給我們在產(chǎn)品設(shè)計方面的啟發(fā),另外清晰的掌握產(chǎn)品和技術(shù)的邊界也是很重要的,我們要明白哪些是可以用技術(shù)手段解決的,哪些是用產(chǎn)品手段解決的,這對于做純軟件的產(chǎn)品經(jīng)理似乎顯得不是那么重要,但是對于物聯(lián)網(wǎng)或者人工智能的產(chǎn)品而言,就很重要了,好了我們開始吧。

          一、什么是MQTT

          1、MQTT

          MQTT協(xié)議(Message Queue Telemetry Transport,消息隊列遙測傳輸協(xié)議)是IBM于1999年為了一個通過衛(wèi)星網(wǎng)絡(luò)連接輸油管道的項目開發(fā)的。MQTT具備實現(xiàn)簡單、支持三種Qos級別、輕量、占帶寬低、可保持持續(xù)回話、可傳輸任意類型數(shù)據(jù)等特點,這讓它非常適合計算能力有限、網(wǎng)絡(luò)帶寬低、信號不穩(wěn)定的遠(yuǎn)程設(shè)備,所以它成為了物聯(lián)網(wǎng)系統(tǒng)事實上的網(wǎng)絡(luò)協(xié)議標(biāo)準(zhǔn)。

          2、MQTT的特性

          簡單來說,MQTT具備以下的特性:

          • 基于TCP協(xié)議的應(yīng)用層協(xié)議; (MQTT協(xié)議是運行在應(yīng)用層的協(xié)議,底層使用TCP協(xié)議進(jìn)行數(shù)據(jù)傳輸,整個協(xié)議棧運行在IP網(wǎng)絡(luò)上,這一點不同于我們經(jīng)常提到的LoRaWAN,他們是在物理層/鏈路層的協(xié)議,他們解決的設(shè)備如何接入互聯(lián)網(wǎng)的問題。

          • 采用C/S架構(gòu);

          • 使用訂閱/發(fā)布模式;(采用訂閱/發(fā)布模式將消息的發(fā)送方和接受方解耦,這種模式更好的契合了物聯(lián)網(wǎng)的場景,具備更好的可擴展性)

          • 提供3種消息的QoS (3種Qos是指三種安全模式,保證只多一次、最少一次、只有一次,可兼容不同場景的需求。)

          • 收發(fā)消息都是異步的,發(fā)送方不需要等待接收方應(yīng)答。

          二、MQTT協(xié)議詳解

          1、MQTT協(xié)議的通信模型

          我們先來看看MQTT協(xié)議的通信模型: 

          可以看到在MQTT協(xié)議中,發(fā)布方和訂閱房并沒有直接連接,而是通過了中間的角色進(jìn)行了一次中轉(zhuǎn),在MQTT協(xié)議中,我們通常將中間的中轉(zhuǎn)角色成為Broker,發(fā)送消息和接收消息的訂閱方成為Client。

          我們一起來看看信息交互的流程: 

          (1)發(fā)布方和訂閱方都建立了到Broker的TCP連接;

          (2)訂閱方告知Broker他要訂閱的主題,主題我們成為Topic;

          (3)發(fā)布方將消息發(fā)送到Broker,并指定相應(yīng)的Topic; 

          (4)Broker接收到消息以后,檢查都有哪些訂閱方訂閱了這個Topic,然后將消息發(fā)送到這些訂閱方; 

          (5)訂閱方從Broker獲取到這些信息; 

          (6)如果訂閱方此時與Broker處于中斷中泰,Broker也可以先保存這條消息,當(dāng)訂閱方在線時,將消息發(fā)送給訂閱方。

          2、MQTT Client

          任何終端,無論是嵌入式設(shè)備,還是服務(wù)器,只要運行了MQTT協(xié)議的庫或者代碼并連接了MQTT Broker,我們都稱其為MQTT Client。Publisher(發(fā)布方)和Subscriber(訂閱方)都屬于Client。一個Client是Pushlisher還是Subscriber,只取決于該Client當(dāng)前的狀態(tài)——是在發(fā)布消息還是在訂閱消息。當(dāng)然,一個Client可以同時是Publisher和Subscriber。

          在大多數(shù)情況下,我們不需要自己按照MQTT的協(xié)議規(guī)范來實現(xiàn)一個MQTT Client,因為MQTT Client庫在很多語言中都有實現(xiàn),包括Android、Arduino、Ruby、C、C++、C#、Go、iOS、Java、JavaScript以及.NET等。

          3、MQTT Broker

          搭建一個完整的MQTT協(xié)議環(huán)境,除了需要MQTT Client外,我們還需要一個MQTT Broker。如前文所述,Broker負(fù)責(zé)接收Publisher的消息,并將消息發(fā)送給相應(yīng)的Subscriber,它是整個MQTT協(xié)議訂閱/發(fā)布的核心。在實際應(yīng)用中,一個MQTT Broker還應(yīng)該提供如下功能: 

          • 可以對Client的接入進(jìn)行授權(quán),并對Client進(jìn)行權(quán)限控制; 

          • 可以橫向擴展,比如集群,滿足海量的Client接入;

          • 有較好的擴展性,可以比較方便地接入現(xiàn)有業(yè)務(wù)系統(tǒng); 

          • 易于監(jiān)控,滿足高可用性。

          4、Client與Broker的連接

          4.1 建立連接

          Client在可以發(fā)布和訂閱消息之前,必須先連接到Broker,看看這個流程圖: 

          (1)Client向Broker發(fā)送一個CONNECT數(shù)據(jù)包; 

          (2)Broker在收到Client的CONNECT數(shù)據(jù)包后,如果允許Client接入,則回復(fù)一個CONNACK包,該CONNACK包的返回碼為0,表示MQTT協(xié)議連接建立成功;如果不允許Client接入,也回復(fù)一個CONNACK包,該CONNACK包的返回碼為一個非0的值,用來標(biāo)識接入失敗的原因,然后斷開底層的TCP連接。

          4.2 關(guān)閉連接

          MQTT協(xié)議的連接關(guān)閉可以由Client或Broker兩者任意一方發(fā)起:Cliennt主動關(guān)閉連接:Client主動關(guān)閉連接的流程非常簡單,只需要向Broker發(fā)送一個DISCONNECT數(shù)據(jù)包就可以了。如果Client沒有發(fā)送DISCONNECT就斷開了連接,那么Broker會認(rèn)為Client是異常中斷的,此時就會向在連接的時候指定的遺愿主題發(fā)布遺愿消息。

          Broker主動關(guān)閉連接:MQTT協(xié)議規(guī)定Broker在沒有收到Client的DISCONNECT數(shù)據(jù)包之前都應(yīng)該保持和Client的連接,只有Broker在Keepalive的時間間隔里,沒有收到Client的任何MQTT協(xié)議數(shù)據(jù)包時才會主動關(guān)閉連接。一些Broker的實現(xiàn)在MQTT協(xié)議上做了一些拓展,支持Client的連接管理,可以主動斷開和某個Client的連接。Broker主動關(guān)閉連接之前不需要向Client發(fā)送任何MQTT協(xié)議數(shù)據(jù)包,直接關(guān)閉底層的TCP連接就可以。

          5、訂閱與發(fā)布

          5.1 訂閱一個主題

          ClientB想要接收ClientA發(fā)布到某個主題的消息,就必須先向Broker訂閱這個主題,訂閱一個主題的流程如圖: 

          (1)Client向Broker發(fā)送一個SUBSCRIBE數(shù)據(jù)包,其中包含Client想要訂閱的主題以及其他參數(shù)。 

          (2)Broker收到SUBSCRIBE數(shù)據(jù)包后,向Client發(fā)送一個SUBACK數(shù)據(jù)包作為應(yīng)答。 

          具體的數(shù)據(jù)內(nèi)容我們就不詳細(xì)看了,對產(chǎn)品經(jīng)理而言,知道這些足夠了。

          5.2 取消訂閱

          Subscriber也可以取消對某些主題的訂閱。取消訂閱的流程如圖:? 

          (1)Client向Broker發(fā)送一個UNSUBSCRIBE數(shù)據(jù)包,其中包含Client想要取消訂閱的主題。 

          (2)Broker收到UNSUBSCRIBE數(shù)據(jù)包后,向Client發(fā)送一個UNSUBACK數(shù)據(jù)包作為應(yīng)答。

          6.MQTT中的Qos

          作為最初用來在網(wǎng)絡(luò)帶寬窄、信號不穩(wěn)定的環(huán)境下傳輸數(shù)據(jù)的協(xié)議,MQTT協(xié)議設(shè)計了一套保證消息穩(wěn)定傳輸?shù)臋C制,包括消息應(yīng)答、存儲和重傳。在這套機制下,MQTT協(xié)議還提供了3種不同層次的QoS。

          6.1 Qos0

          At most once,至多一次,表示發(fā)送方發(fā)送一條消息,接收方最多能收到一次,也就是說Sender盡力向接收方發(fā)送消息,如果發(fā)送失敗,則放棄。

          Qos0所消耗的資源最少,但是可能存在丟包,我們思考一個問題,對于一個上報數(shù)據(jù)很頻繁的傳感器,即使丟掉一兩條數(shù)據(jù),問題也不大,這種場景下Qos0很顯然是適用的。

          6.2 Qos1

          At least once,至少一次,表示發(fā)送方發(fā)送一條消息,接收方至少能收到一次,也就是說發(fā)送方向接收方發(fā)送消息,如果發(fā)送失敗,發(fā)送方會繼續(xù)重試,直到接收方收到消息為止,但是因為重傳的原因,接收方可能會收到重復(fù)的消息。

          流程是這樣的: 

          (1)發(fā)送方向接收方發(fā)送一個帶有消息數(shù)據(jù)的PUBLISH數(shù)據(jù)包,并在本地保存這個PUBLISH數(shù)據(jù)包。 

          (2)接收方在收到PUBLISH數(shù)據(jù)包后,向發(fā)送方發(fā)送一個PUBACK數(shù)據(jù)包,PUBACK數(shù)據(jù)包沒有消息體,只在可變頭中有一個包標(biāo)識(Packet Identifier),和它收到的PUBLISH數(shù)據(jù)包中的Packet Identifier一致。 

          (3)發(fā)送方在收到PUBACK數(shù)據(jù)包之后,根據(jù)PUBACK數(shù)據(jù)包中的Packet Identifier找到本地保存的PUBLISH數(shù)據(jù)包,然后丟棄,這樣一次消息發(fā)送完成。 

          (4)如果發(fā)送方在一段時間內(nèi)沒有收到PUBLISH數(shù)據(jù)包對應(yīng)的PUBACK數(shù)據(jù)包,那么它會將PUBLISH數(shù)據(jù)包中的DUP標(biāo)識設(shè)為1(代表的是重新發(fā)送PUBLISH數(shù)據(jù)包),然后重新發(fā)送該PUBLISH數(shù)據(jù)包。重復(fù)這個流程,直到發(fā)送方收到PUBACK數(shù)據(jù)包,然后執(zhí)行第3步。

          需要注意的是需要對數(shù)據(jù)進(jìn)行去重,去重方式也很簡單,只要在消息內(nèi)包含消息的ID就行,通常用的是UUID。

          6.3 Qos2

          Exactly once,確保只有一次,表示發(fā)送方發(fā)送一條消息,接收方確保能收到且只收到一次,也就是說發(fā)送方盡力向接收方發(fā)送消息,如果發(fā)送失敗,會繼續(xù)重試,直到接收方收到消息為止,同時保證接收方不會因為消息重傳而收到重復(fù)的消息。

          QoS2使用2套請求/應(yīng)答流程(一個4段的握手)來確保接收方收到來自發(fā)送方的消息,且不重復(fù)。 

          (1)發(fā)送方發(fā)送QoS值為2的PUBLISH數(shù)據(jù)包,假設(shè)該數(shù)據(jù)包中Packet Identifier為P,并在本地保存該PUBLISH數(shù)據(jù)包。 

          (2)接收方收到PUBLISH數(shù)據(jù)包后,在本地保存PUBLISH數(shù)據(jù)包的Packet Identifier為P,并回復(fù)發(fā)送方一個PUBREC數(shù)據(jù)包。PUBREC數(shù)據(jù)包可變頭中的Packet Identifier為P,沒有消息體。 

          (3)當(dāng)發(fā)送方收到PUBREC數(shù)據(jù)包后,它就可以安全地丟掉初始的Packet Identifier為P的PUBLISH數(shù)據(jù)包,同時保存該PUBREC數(shù)據(jù)包,并回復(fù)接收方一個PUBREL數(shù)據(jù)包。PUBREL數(shù)據(jù)包可變頭中的Packet Identifier為P,沒有消息體;如果發(fā)送方在一定時間內(nèi)沒有收到PUBREC數(shù)據(jù)包,它會把PUBLISH數(shù)據(jù)包的DUP標(biāo)識設(shè)為1,重新發(fā)送該PUBLISH數(shù)據(jù)包。 

          (4)當(dāng)接收方收到PUBREL數(shù)據(jù)包時,它可以丟棄掉保存的PUBLISH數(shù)據(jù)包的Packet Identifier P,并回復(fù)發(fā)送方一個PUBCOMP數(shù)據(jù)包。PUBCOMP數(shù)據(jù)包可變頭中的Packet Identifier為P,沒有消息體。 

          (5)當(dāng)發(fā)送方收到PUBCOMP數(shù)據(jù)包,它會認(rèn)為數(shù)據(jù)包傳輸已完成,會丟掉對應(yīng)的PUBREC數(shù)據(jù)包。如果發(fā)送方在一定時間內(nèi)沒有收到PUBCOMP數(shù)據(jù)包,則會重新發(fā)送PUBREL數(shù)據(jù)包。

          可以看到,Qos2也是最安全,但是效率最低的一種Qos等級。

          7.Retained

          關(guān)于Retained我們可以這樣來理解,想象一個場景,你有一個溫度傳感器,它每3個小時向一個主題發(fā)布當(dāng)前溫度。那么問題來了,有一個新的訂閱者在它剛剛發(fā)布了當(dāng)前溫度之后訂閱了這個主題,那么這個訂閱端什么時候才能收到溫度消息?沒錯,和你想的一樣,它必須等到3個小時以后,溫度傳感器再次發(fā)布消息的時候才能收到。在這之前,這個新的訂閱者對傳感器的溫度數(shù)據(jù)一無所知。這時候我們就可以用到Retained消息來解決這個問題。

          Retained消息是指在PUBLISH數(shù)據(jù)包中將Retain標(biāo)識設(shè)為1的消息,Broker收到這樣的PUBLISH數(shù)據(jù)包以后,將為該主題保存這個消息,當(dāng)一個新的訂閱者訂閱該主題時,Broker會馬上將這個消息發(fā)送給訂閱者。Retain消息有如下特點:

          • 一個Topic只能有一條Retained消息,發(fā)布新的Retained消息將覆蓋舊的Retained消息;

          • 如果訂閱者使用通配符訂閱主題,那他會收到所有匹配主題的Retained消息;

          • 只有新的訂閱者才會收到Retained消息,如果訂閱者重復(fù)訂閱一個主題,那么在每次訂閱的時候都會被當(dāng)作新的訂閱者,然后收到Retained消息。

          8.LWT

          LWT全稱為Last Will and Testament,也就是我們在連接Broker時提到的遺愿,包括遺愿主題、遺愿QoS、遺愿消息等。顧名思義,當(dāng)Broker檢測到Client非正常地斷開連接時,就會向Client的遺愿主題中發(fā)布一條消息。遺愿的相關(guān)設(shè)置是在建立連接時,在CONNECT數(shù)據(jù)包里面指定的。LWT配合Retained可以用于監(jiān)測設(shè)備的連接狀態(tài): 

          (1)Client在連接時指定Will Topic為“client/status”,遺愿消息為“offline”,Will Retain=1; 

          (2)Client在連接成功后向同一個主題“client/status”發(fā)布一個內(nèi)容為“online”的Retained消息。那么,訂閱者在任何時候訂閱“client/status”,都會獲取Client當(dāng)前的連接狀態(tài)。

          9.Keepalive

          在生產(chǎn)環(huán)境下,特別是物聯(lián)網(wǎng)這種無人值守的設(shè)備比較多的情況下,我們都希望設(shè)備能夠自動從錯誤中恢復(fù)過來,比如在網(wǎng)絡(luò)故障恢復(fù)以后,設(shè)備能夠自動重新連接Broker。而Keepalive的存在就是為了實時監(jiān)測設(shè)備的連接狀態(tài),以及時的完成?;睢T诮⑵疬B接的時候我們會傳遞一個Keepalive的參數(shù),單位為秒。MQTT協(xié)議規(guī)定,在1.5倍Keeplive的時間間隔內(nèi),如果Broker沒有收到來自Cilent的任何數(shù)據(jù)包,那么就認(rèn)為已經(jīng)斷開了。但是我們不能保證每一個1.5倍Keepalive中都剛好有數(shù)據(jù)傳輸,因此MQTT協(xié)議中設(shè)計了PINGREQ/PINGRESP數(shù)據(jù)包,在Cilent與Broker之間沒有數(shù)據(jù)傳輸?shù)臅r候,可以通過該機制傳輸非常小的數(shù)據(jù)內(nèi)容來滿足Keepalive的約定。值得注意的是,Keepalive還有這樣的特性: 

          (1)如果在一個Keepalive時間間隔內(nèi),Client和Broker有過數(shù)據(jù)包傳輸,比如PUBLISH數(shù)據(jù)包,那Client就沒有必要再使用PINGREQ數(shù)據(jù)包了,在網(wǎng)絡(luò)資源比較緊張的情況下這點很重要; 

          (2)Keepalive的值是由Client指定的,不同的Client可以指定不同的值; 

          (3)Keepalive的最大值為18個小時12分15秒; 

          (4)Keepalive的值如果設(shè)為0的話,代表不使用Keepalive機制。


          瀏覽 78
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人综合娱乐在线视频 | 日韩成人电影中文字幕 | 后入极品在线 | 美女高潮喷水视频 | 日日干日日色 |