標(biāo)題: MQTT協(xié)議介紹之二:連接 [打印本頁(yè)]
作者: z3512641347 時(shí)間: 2017-8-25 08:57
標(biāo)題: MQTT協(xié)議介紹之二:連接
在機(jī)智云的整個(gè)架構(gòu)里面,如上圖,GAgent實(shí)現(xiàn)了從模塊到云端的數(shù)據(jù)交互,其實(shí)GAgent里面就是用MQTT協(xié)議實(shí)現(xiàn)的,可見MQTT協(xié)議的重要性。今天介紹MQTT的發(fā)布、訂閱和取消訂閱。
回顧
在上一篇文章中,我們解釋了發(fā)布/訂閱模式是如何工作的以及如何在MQTT中應(yīng)用,以下我們把要點(diǎn)回顧下:發(fā)布或者訂閱解耦一個(gè)客戶端,就是從另一個(gè)客戶端(或更多客戶端)發(fā)送特定消息(稱為發(fā)布者),為了確定哪個(gè)消息發(fā)送到哪個(gè)客戶端,MQTT使用了主題。主題是層次結(jié)構(gòu)的字符串,用于消息過(guò)濾和路由。
在上一章節(jié)的最后我又更具理論性的分析了,發(fā)布/訂閱是什么,以及如何從消息排隊(duì)方法中區(qū)分MQTT。這篇文章干貨將更多,主要介紹MQTT的基本知識(shí)。這一章,我們討論的主題是MQTT客戶端和代理服務(wù)器的定義以及MQTT連接的基礎(chǔ)知識(shí),如何連接、連接需要的參數(shù)。
引言
我們已經(jīng)看看完了MQTT的發(fā)布和訂閱后,所有的設(shè)備都要和代理服務(wù)器連接的,我們?cè)谥v連接之前應(yīng)該理解下客戶端和代理服務(wù)器。
客戶端
在文章中,我們討論的客戶端都是MQTT客戶端,說(shuō)的發(fā)布者和訂閱者也都指的是MQTT客戶端的發(fā)布和訂閱(通常,MQTT客戶端可以同時(shí)發(fā)布和訂閱)MQTT客戶端是從微控制器到完整的服務(wù)器的任何設(shè)備,它具有運(yùn)行的MQTT庫(kù),并通過(guò)任何類型的網(wǎng)絡(luò)連接到MQTT代理。這是一個(gè)非常小且資源有限的設(shè)備它通過(guò)無(wú)線網(wǎng)絡(luò)連接,并且設(shè)定一定參數(shù),或者運(yùn)行圖形化MQTT客戶端的典型計(jì)算機(jī)用于測(cè)試目的,總的來(lái)說(shuō)基本上是具有TCP / IP協(xié)議棧并在其上支持MQTT協(xié)議的任何設(shè)備。
MQTT協(xié)議的客戶端實(shí)現(xiàn)非常直觀,簡(jiǎn)單,有人會(huì)問了,為什么MQTT非常適合小型設(shè)備呢?MQTT客戶端庫(kù)可用于各種各樣的編程語(yǔ)言,如Android, Arduino, C, C++, C#, Go, iOS, Java, JavaScript, .NET. 可以在維基百科上找到MQTT的完整的列表。
代理
MQTT客戶端的對(duì)應(yīng)方就是MQTT代理服務(wù)器,這是任何發(fā)布和訂閱協(xié)議的核心,根據(jù)具體實(shí)現(xiàn)情況,代理可以處理多達(dá)數(shù)千個(gè)并發(fā)連接的MQTT客戶端。代理主要負(fù)責(zé)接收所有消息,過(guò)濾它們,決定誰(shuí)對(duì)其感興趣,然后將消息發(fā)送給相應(yīng)訂閱客戶端。它還擁有所有持久客戶端的會(huì)話,包括訂閱和錯(cuò)過(guò)的消息。
代理的另一責(zé)任是給客戶端認(rèn)證和授權(quán),而且在大多數(shù)時(shí)候,代理也是可擴(kuò)展的,這樣可以輕松地自定義身份驗(yàn)證,授權(quán)并且集成到后端系統(tǒng)中。集成是一個(gè)重要的方面,因?yàn)榇硗ǔJ侵苯颖┞对诨ヂ?lián)網(wǎng)上并處理大量客戶端的組件,然后將消息傳遞到下游分析和處理系統(tǒng)。
正如我們?cè)谖覀冊(cè)缙诓┛椭兴枋龅囊粯樱嗛喫邢⒉⒉皇且粋(gè)真正的選擇,所有的代理都是中心樞紐,每個(gè)消息都需要通過(guò)它的。因此,重要的是,它具有高度可擴(kuò)展性,可集成到后端系統(tǒng)中,這樣易于監(jiān)控,當(dāng)然也具有抗故障性,才能保障穩(wěn)定。例如,HiveMQ通過(guò)使用最先進(jìn)的事件驅(qū)動(dòng)網(wǎng)絡(luò)處理,一個(gè)開放的插件系統(tǒng)和標(biāo)準(zhǔn)的監(jiān)控為用戶提供服務(wù)。
MQTT連接
MQTT協(xié)議基于TCP / IP的,客戶端和代理都需要具有TCP / IP協(xié)議棧。
33.jpg (12.19 KB, 下載次數(shù): 103)
下載附件
2017-8-25 08:56 上傳
MQTT連接本身始終在一個(gè)客戶端和代理之間,沒有客戶端直接連接到另一個(gè)客戶端。通過(guò)客戶端向代理發(fā)送CONNECT消息來(lái)啟動(dòng)連接。具有CONNACK的代理響應(yīng)并發(fā)送狀態(tài)代碼。建立連接后,只要客戶端沒有發(fā)送斷開連接命令或者斷開連接網(wǎng)絡(luò),代理將一直保持打開狀態(tài)。
44.jpg (15.9 KB, 下載次數(shù): 98)
下載附件
2017-8-25 08:57 上傳
MQTT通過(guò)NAT連接 MQTT客戶端一般是連接路由器設(shè)備的,它們正在使用網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT),以便從專用網(wǎng)絡(luò)地址(如192.168.x.x,10.0.x.x)轉(zhuǎn)換為面向公眾的公共網(wǎng)絡(luò)。如前所述,MQTT客戶端第一步就要要發(fā)送CONNECT消息。因此,NAT后面的客戶端沒有任何問題,因?yàn)榇砭哂泄驳刂,并且連接將保持打開,以允許在初始CONNECT之后雙向發(fā)送和接收消息。
下面讓我們看看MQTT客戶端發(fā)送的連接信息。前面已經(jīng)提到,這是從客戶端到代理發(fā)起連接。如果CONNECT消息格式錯(cuò)誤(根據(jù)MQTT規(guī)范)或打開網(wǎng)路超時(shí),代理將關(guān)閉連接。這是合理的行為,這樣可以避免惡意客戶端攻擊,減慢代理的速度。
一個(gè)完好的客戶端將發(fā)送一個(gè)包含以下內(nèi)容的連接消息:
55.jpg (23.13 KB, 下載次數(shù): 70)
下載附件
2017-8-25 08:57 上傳
此外,CONNECT消息中還包含其他信息,這對(duì)MQTT庫(kù)的編寫者而言比對(duì)庫(kù)的使用者更加關(guān)心。如果您對(duì)詳細(xì)信息有興趣,請(qǐng)查看MQTT 3.1.1規(guī)范。 下面讓我們逐個(gè)瀏覽所有這些項(xiàng)目參數(shù)吧:
客戶端標(biāo)識(shí)符(簡(jiǎn)稱ClientId)是連接到MQTT代理的每個(gè)MQTT客戶端的標(biāo)識(shí)符。正如標(biāo)識(shí)符的含義那樣,每個(gè)代理應(yīng)該是唯一的。代理使用它來(lái)識(shí)別客戶端和客戶端的當(dāng)前狀態(tài)。如果不需要一個(gè)狀態(tài)來(lái)保持代理,在MQTT 3.1.1(當(dāng)前標(biāo)準(zhǔn))中,也可以發(fā)送一個(gè)空的ClientId。這導(dǎo)致沒有任何狀態(tài)的連接,條件是 Clean Session是真的,否則連接將被拒絕。
Clean Session標(biāo)志指示代理,客戶端是否要建立持久會(huì)話。持久會(huì)話(CleanSession為假)表示代理將存儲(chǔ)客戶端的所有訂閱以及所有錯(cuò)過(guò)的信息。當(dāng)使用服務(wù)質(zhì)量(QoS)1或2進(jìn)行訂閱時(shí)。如果Clean Session設(shè)置為真,則代理不會(huì)為客戶端存儲(chǔ)任何東西,并且還將清除以前持續(xù)會(huì)話中的所有信息。
MQTT允許發(fā)送用于驗(yàn)證客戶端的用戶名和密碼以及授權(quán)。然而,密碼是以明文形式發(fā)送的,如果它沒有通過(guò)實(shí)現(xiàn)加密或散列,或者使用TLS。我們強(qiáng)烈建議使用用戶名和密碼以及安全的傳輸,在像HiveMQ這樣的代理中,也可以使用SSL證書對(duì)客戶端進(jìn)行身份驗(yàn)證,因此不需要用戶名和密碼。
Will Message是MQTT的最后一個(gè)意愿和遺囑特征的一部分。它允許通知其他客戶端,當(dāng)客戶端不正常地?cái)嚅_連接。連接客戶端將在CONNECT消息中以MQTT消息和主題的形式提供他的意愿。如果客戶端不正常地?cái)嚅_連接,代理客戶端會(huì)發(fā)送此消息。我們會(huì)在后面的文章中單獨(dú)介紹一下。
KeepAlive是一個(gè)時(shí)間間隔,客戶端通過(guò)向代理發(fā)送常規(guī)PING請(qǐng)求消息。代理將與PING響應(yīng),這種機(jī)制將確定雙方是否仍然存在和正常通信。這個(gè)我們將在以后的一篇文章中詳細(xì)介紹一下。這基本上都是從MQTT客戶端連接到MQTT代理所需的所有信息。每個(gè)MQTT庫(kù)通常都會(huì)有其他選項(xiàng),可以進(jìn)行具體配置。
當(dāng)代理獲得CONNECT消息時(shí),代理有義務(wù)使用CONNACK消息進(jìn)行響應(yīng)。CONNACK只包含兩個(gè)數(shù)據(jù)條目:會(huì)話存在標(biāo)志,連接確認(rèn)標(biāo)志。
會(huì)話存在標(biāo)志指示,代理是否已經(jīng)具有來(lái)自先前交互的客戶端的持久會(huì)話。如果客戶端連接并將CleanSession設(shè)置為真,則此標(biāo)志始終為假,因?yàn)闆]有會(huì)話可用。如果客戶端將CleanSession設(shè)置為假,則該標(biāo)志取決于該ClientId是否存在可用于的會(huì)話信息。如果存儲(chǔ)會(huì)話信息,則該標(biāo)志為真,否則為假。該標(biāo)志在MQTT 3.1.1中新添加,并幫助客戶端確定是否必須訂閱主題,或者是否仍然存儲(chǔ)在他的會(huì)話中。
CONNACK中的第二個(gè)標(biāo)志是連接確認(rèn)標(biāo)志。它指示客戶端,是否連接成功和沒有連接成功的原因是什么。
在下表中,您可以一目了然地看到所有的返回代碼。
66.jpg (14.1 KB, 下載次數(shù): 98)
下載附件
2017-8-25 08:57 上傳
這些更詳細(xì)的說(shuō)明可以在MQTT規(guī)范中找到 問題
您可能會(huì)問,即使沒有發(fā)送消息,MQTT如何保持連接的打開狀態(tài)?或者如何知道連接何時(shí)丟失?你必須耐心等待,但是我們將在后面的整個(gè)博客里面寫下一些關(guān)于這個(gè)主題的必要內(nèi)容。
77.jpg (16.33 KB, 下載次數(shù): 81)
下載附件
2017-8-25 08:57 上傳
這就是我們的MQTT 要點(diǎn)系列的第三部分的結(jié)尾。我們希望您能了解至少一件關(guān)于MQTT的基本知識(shí),并期待下一篇關(guān)于如何在MQTT中發(fā)布,訂閱和取消訂閱的文章。 學(xué)習(xí)總結(jié)
都是很重點(diǎn)的內(nèi)容,可以先看看這個(gè)文檔再去看官方協(xié)議,畢竟這個(gè)要比官方協(xié)議講的要通俗易懂些,很有收獲的。
歡迎光臨 (http://www.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |