物聯(lián)網(wǎng) (IoT) 設(shè)備必須連接互聯(lián)網(wǎng)。通過連接到互聯(lián)網(wǎng),設(shè)備就能相互協(xié)作,以及與后端服務(wù)協(xié)同工作;ヂ(lián)網(wǎng)的基礎(chǔ)網(wǎng)絡(luò)協(xié)議是 TCP/IP。MQTT(消息隊(duì)列遙測(cè)傳輸) 是基于 TCP/IP 協(xié)議棧而構(gòu)建的,已成為 IoT 通信的標(biāo)準(zhǔn)。 MQTT 最初由 IBM 于上世紀(jì) 90 年代晚期發(fā)明和開發(fā)。它最初的用途是將石油管道上的傳感器與衛(wèi)星相鏈接。顧名思義,它是一種支持在各方之間異步通信的消息協(xié)議。異步消息協(xié)議在空間和時(shí)間上將消息發(fā)送者與接收者分離,因此可以在不可靠的網(wǎng)絡(luò)環(huán)境中進(jìn)行擴(kuò)展。雖然叫做消息隊(duì)列遙測(cè)傳輸,但它與消息隊(duì)列毫無關(guān)系,而是使用了一個(gè)發(fā)布和訂閱的模型。在 2014 年末,它正式成為了一種 OASIS 開放標(biāo)準(zhǔn),而且在一些流行的編程語言中受到支持(通過使用多種開源實(shí)現(xiàn))。 為何選擇 MQTT MQTT 是一種輕量級(jí)的、靈活的網(wǎng)絡(luò)協(xié)議,致力于為 IoT 開發(fā)人員實(shí)現(xiàn)適當(dāng)?shù)钠胶猓?br /> 1、這個(gè)輕量級(jí)協(xié)議可在嚴(yán)重受限的設(shè)備硬件和高延遲/帶寬有限的網(wǎng)絡(luò)上實(shí)現(xiàn)。 2、它的靈活性使得為 IoT 設(shè)備和服務(wù)的多樣化應(yīng)用場(chǎng)景提供支持成為可能。 為了了解為什么 MQTT 如此適合 IoT 開發(fā)人員,我們首先來分析一下為什么其他流行網(wǎng)絡(luò)協(xié)議未在 IoT 中得到成功應(yīng)用。 為什么不選擇HTTP 大多數(shù)開發(fā)人員已經(jīng)熟悉 HTTP Web 服務(wù)。那么為什么不讓 IoT 設(shè)備連接到 Web 服務(wù)?設(shè)備可采用 HTTP 請(qǐng)求的形式發(fā)送其數(shù)據(jù),并采用 HTTP 響應(yīng)的形式從系統(tǒng)接收更新。這種請(qǐng)求和響應(yīng)模式存在一些嚴(yán)重的局限性: 1、HTTP 是一種同步協(xié)議?蛻舳诵枰却⻊(wù)器響應(yīng)。Web 瀏覽器具有這樣的要求,但它的代價(jià)是犧牲了可伸縮性。在 IoT 領(lǐng)域,大量設(shè)備以及很可能不可靠或高延遲的網(wǎng)絡(luò)使得同步通信成為問題。異步消息協(xié)議更適合 IoT 應(yīng)用程序。傳感器發(fā)送讀數(shù),讓網(wǎng)絡(luò)確定將其傳送到目標(biāo)設(shè)備和服務(wù)的最佳路線和時(shí)間。 2、HTTP 是單向的。客戶端必須發(fā)起連接。在 IoT 應(yīng)用程序中,設(shè)備或傳感器通常是客戶端,這意味著它們無法被動(dòng)地接收來自網(wǎng)絡(luò)的命令。 3、HTTP 是一種 1-1 協(xié)議?蛻舳税l(fā)出請(qǐng)求,服務(wù)器進(jìn)行響應(yīng)。將消息傳送到網(wǎng)絡(luò)上的所有設(shè)備上,不但很困難,而且成本很高,而這是 IoT 應(yīng)用程序中的一種常見使用情況。 4、HTTP 是一種有許多標(biāo)頭和規(guī)則的重量級(jí)協(xié)議。它不適合受限的網(wǎng)絡(luò)。 HTTP協(xié)議的兩個(gè)過程,Request和Response,兩個(gè)都有各自的語言格式,我們看下是什么。 請(qǐng)求報(bào)文格式:(注意這里有個(gè)換行) 響應(yīng)報(bào)文格式:(注意這里有個(gè)換行) 方法method: 這個(gè)很重要,比如說GET和POST方法,這兩個(gè)是很常用的,GET就是獲取什么內(nèi)容,而POST就是向服務(wù)器發(fā)送什么數(shù)據(jù)。當(dāng)然還有其他的,比如HTTP 1.1中還有:DELETE、PUT、CONNECT、HEAD、OPTIONS、TRACE等一共8個(gè)方法(HTTP Method歷史:HTTP 0.9 只有GET方法;HTTP 1.0 有GET、POST、HEAD三個(gè)方法)。 請(qǐng)求URL: 這里填寫的URL是不包含IP地址或者域名的,是主機(jī)本地文件對(duì)應(yīng)的目錄地址,所以我們一般看到的就是“/”。 版本version: 格式是HTTP/ 狀態(tài)碼status: 狀態(tài)碼是三個(gè)數(shù)字,代表的是請(qǐng)求過程中所發(fā)生的情況,比如說200代表的是成功,404代表的是找不到文件。 原因短語reason-phrase: 是狀態(tài)碼的可讀版本,狀態(tài)碼就是一個(gè)數(shù)字,如果你事先不知道這個(gè)數(shù)字什么意思,可以先查看一下原因短語。 首部header: 注意這里的header我們不是叫做頭,而是叫做首部?赡苡辛銈(gè)首部也可能有多個(gè)首部,每個(gè)首部包含一個(gè)名字后面跟著一個(gè)冒號(hào),然后是一個(gè)可選的空格,接著是一個(gè)值,然后換行。 實(shí)體的主體部分entity-body: 實(shí)體的主體部分包含一個(gè)任意數(shù)據(jù)組成的數(shù)據(jù)塊,并不是所有的報(bào)文都包含實(shí)體的主體部分,有時(shí)候只是一個(gè)空行加換行就結(jié)束了。 下面我們舉個(gè)簡(jiǎn)單的例子: 請(qǐng)求報(bào)文: GET /index.html HTTP/1.1 Accept: text/* Host: www.myweb.com 響應(yīng)報(bào)文: HTTP/1.1 200 OK Content-type: text/plain Content-length: 3 出于上述原因,大部分高性能、可擴(kuò)展的系統(tǒng)都使用異步消息總線來進(jìn)行內(nèi)部數(shù)據(jù)交換,而不使用 Web 服務(wù)。事實(shí)上,企業(yè)中間件系統(tǒng)中使用的最流行的消息協(xié)議被稱為 AMQP(高級(jí)消息排隊(duì)協(xié)議)。但是,在高性能環(huán)境中,計(jì)算能力和網(wǎng)絡(luò)延遲通常不是問題。AMQP 致力于在企業(yè)應(yīng)用程序中實(shí)現(xiàn)可靠性和互操作性。它擁有龐大的特性集,但不適合資源受限的 IoT 應(yīng)用程序。 除了 AMQP 之外,還有其他流行的消息協(xié)議。例如,XMPP(Extensible Messaging and Presence Protocol,可擴(kuò)展消息和狀態(tài)協(xié)議)是一種對(duì)等即時(shí)消息 (IM) 協(xié)議。它高度依賴于支持 IM 用例的特性,比如存在狀態(tài)和介質(zhì)連接。與 MQTT 相比,它在設(shè)備和網(wǎng)絡(luò)上需要的資源都要多得多。 那么,MQTT 為什么如此輕量且靈活?MQTT 協(xié)議的一個(gè)關(guān)鍵特性是發(fā)布和訂閱模型。與所有消息協(xié)議一樣,它將數(shù)據(jù)的發(fā)布者與使用者分離。 它具有以下主要的幾項(xiàng)特性: 1、使用發(fā)布/訂閱消息模式,提供一對(duì)多的消息發(fā)布和應(yīng)用程序之間的解耦; 2、消息傳輸不需要知道負(fù)載內(nèi)容; 3、使用 TCP/IP 提供網(wǎng)絡(luò)連接; 4、有三種消息發(fā)布的服務(wù)質(zhì)量: QoS 0:“最多一次”,消息發(fā)布完全依賴底層 TCP/IP 網(wǎng)絡(luò)。分發(fā)的消息可能丟失或重復(fù)。例如,這個(gè)等級(jí)可用于環(huán)境傳感器數(shù)據(jù),單次的數(shù)據(jù)丟失沒關(guān)系,因?yàn)椴痪煤筮會(huì)有第二次發(fā)送。 QoS 1:“至少一次”,確保消息可以到達(dá),但消息可能會(huì)重復(fù)。 QoS 2:“只有一次”,確保消息只到達(dá)一次。例如,這個(gè)等級(jí)可用在一個(gè)計(jì)費(fèi)系統(tǒng)中,這里如果消息重復(fù)或丟失會(huì)導(dǎo)致不正確的收費(fèi)。 5、小型傳輸,開銷很小(固定長(zhǎng)度的頭部是 2 字節(jié)),協(xié)議交換最小化,以降低網(wǎng)絡(luò)流量; 6、使用 Last Will 和 Testament 特性通知有關(guān)各方客戶端異常中斷的機(jī)制;在MQTT協(xié)議中,一個(gè)MQTT數(shù)據(jù)包由:固定頭(Fixed header)、 可變頭(Variable header)、 消息體(payload)三部分構(gòu)成。MQTT的傳輸格式非常精小,最小的數(shù)據(jù)包只有2個(gè)bit,且無應(yīng)用消息頭。 發(fā)布和訂閱模型 MQTT 協(xié)議在網(wǎng)絡(luò)中定義了兩種實(shí)體類型:一個(gè)消息代理和一些客戶端。代理是一個(gè)服務(wù)器,它從客戶端接收所有消息,然后將這些消息路由到相關(guān)的目標(biāo)客戶端?蛻舳耸悄軌蚺c代理交互來發(fā)送和接收消息的任何事物。客戶端可以是現(xiàn)場(chǎng)的 IoT 傳感器,或者是數(shù)據(jù)中心內(nèi)處理 IoT 數(shù)據(jù)的應(yīng)用程序。 1、客戶端連接到代理。它可以訂閱代理中的任何消息 “主題”。此連接可以是簡(jiǎn)單的 TCP/IP 連接,也可以是用于發(fā)送敏感消息的加密 TLS 連接。 2、客戶端通過將消息和主題發(fā)送給代理,發(fā)布某個(gè)主題范圍內(nèi)的消息。 3、代理然后將消息轉(zhuǎn)發(fā)給所有訂閱該主題的客戶端。 因?yàn)?MQTT 消息是按主題進(jìn)行組織的,所以應(yīng)用程序開發(fā)人員能靈活地指定某些客戶端只能與某些消息交互。例如,傳感器將在 “sensor_data” 主題范圍內(nèi)發(fā)布讀數(shù),并訂閱 “config_change” 主題。將傳感器數(shù)據(jù)保存到后端數(shù)據(jù)庫中的數(shù)據(jù)處理應(yīng)用程序會(huì)訂閱 “sensor_data” 主題。管理控制臺(tái)應(yīng)用程序能接收系統(tǒng)管理員的命令來調(diào)整傳感器的配置,比如靈敏度和采樣頻率,并將這些更改發(fā)布到 “config_change” 主題。 IoT 傳感器的 MQTT 發(fā)布和訂閱模型 同時(shí),MQTT 是輕量級(jí)的。它有一個(gè)用來指定消息類型的簡(jiǎn)單標(biāo)頭,有一個(gè)基于文本的主題,還有一個(gè)任意的二進(jìn)制有效負(fù)載。應(yīng)用程序可對(duì)有效負(fù)載采用任何數(shù)據(jù)格式,比如 JSON、XML、加密二進(jìn)制或 Base64,只要目標(biāo)客戶端能夠解析該有效負(fù)載。 MQTT 開發(fā)入門 下面我們介紹一下如何利用北京奇跡物聯(lián)的AM20E模組實(shí)現(xiàn)MQTT協(xié)議接入阿里IoT平臺(tái)。AM20E 是一款超小封裝 NB-IoT 工業(yè)級(jí)無線通訊模塊。內(nèi)置多種協(xié)議棧TCP/IP,HTTP,MQTT等,本文我們使用其MQTT協(xié)議接入阿里的IoT平臺(tái),實(shí)現(xiàn)數(shù)據(jù)的上下行。 注冊(cè)阿里云物聯(lián)網(wǎng)平臺(tái) 注冊(cè)阿里云https://account.aliyun.com 注意:需要注冊(cè)后實(shí)名認(rèn)證才可以進(jìn)入“物聯(lián)網(wǎng)平臺(tái)”(更名前叫物聯(lián)網(wǎng)開發(fā)套件),操作中有任何問題可以從阿里云的技術(shù)支持找到對(duì)應(yīng)文檔查看。 注冊(cè)后選擇物聯(lián)網(wǎng)平臺(tái) 在控制臺(tái)后創(chuàng)建產(chǎn)品 點(diǎn)擊創(chuàng)建產(chǎn)品 創(chuàng)建完成產(chǎn)品,點(diǎn)擊查看 點(diǎn)擊前往管理 點(diǎn)擊添加設(shè)備 添加完成設(shè)備后,將此三個(gè)信息記錄下來 在此界面,點(diǎn)擊功能定義 在功能定義界面,新增功能 在消息通信界面,查看Topic,這些Topic我們后期調(diào)試會(huì)用到 暫時(shí)用到的兩個(gè)Topic,為 /sys/a1cn4I14cE9/${deviceName}/thing/event/property/post 設(shè)備屬性上報(bào) /sys/a1cn4I14cE9/${deviceName}/thing/service/property/set 設(shè)備屬性設(shè)置 經(jīng)過上面的準(zhǔn)備,可以開始調(diào)試AM20E與在阿里云建立的設(shè)備上傳下發(fā)數(shù)據(jù)了。 AM20E連接阿里云 阿里云建立的設(shè)備信息: product_key: a1cn4I14cE9 device_name: AM20E00101 device_secret: xL7bM8oKmfOnM6wk9bwNsylJSOQW9kDD 連接流程如下: AT+CSQ +CSQ: 31,99 OK AT+CPIN? +CPIN:READY OK AT+CREG? +CREG: 0,1 OK AT+XIIC=1 OK AT+IMQTTAUTH="a1cn4I14cE9","AM20E00101","xL7bM8oKmfOnM6wk9bwNsylJSOQW9kDD" OK //發(fā)送鑒權(quán)信息 AT+IMQTTPARA="TIMEOUT",2 //設(shè)置參數(shù) OK +IMQTTAUTH:OK AT+IMQTTCONN //連接 OK AT+IMQTTSUB="/sys/a1cn4I14cE9/AM20E00101/thing/event/property/post",2 +IMQTTSUB:1 OK +IMQTTSUB:1,2 //訂閱一個(gè)topic AT+IMQTTPUBS="/sys/a1cn4I14cE9/AM20E00101/thing/event/property/post",1,"{\"id\":\"789\",\"version\":\"1.0\",\"params\":{\"PM25\":25},\"method\":\"thing.event.property.post\"}" +IMQTTPUB:2 OK +IMQTTPUB:2,0 +IMQTTRCVPUB:46438,/sys/a1cn4I14cE9/AM20E00101/thing/event/property/post,86,{"id":"789","version":"1.0","params":{"PM25":25},"method":"thing.event.property.post"} //發(fā)送數(shù)據(jù) AT+IMQTTSUB="/a1cn4I14cE9/AM20E00101/user/get",2 +IMQTTSUB:3 OK +IMQTTSUB:3,2 //訂閱下行的topic,并通過該topic下發(fā)數(shù)據(jù) +IMQTTRCVPUB:0,/a1cn4I14cE9/AM20E00101/user/get,6,123456 //收到的數(shù)據(jù) AT+IMQTTDISCONN //斷開連接 OK 技巧和解決方法 MQTT 的優(yōu)勢(shì)在于它的簡(jiǎn)單性。在可以使用的主題類型或消息有效負(fù)載上沒有任何限制。這支持一些有趣的用例。例如,請(qǐng)考慮以下問題: 如何使用 MQTT 發(fā)送 1-1 消息?雙方可以協(xié)商使用一個(gè)特定于它們的主題。例如,主題名稱可以包含兩個(gè)客戶端的 ID,以確保它的唯一性。 客戶端如何傳輸它的存在狀態(tài)?系統(tǒng)可以為 “presence” 主題協(xié)商一個(gè)命名約定。例如,“presence/client-id” 主題可以擁有客戶端的存在狀態(tài)信息。當(dāng)客戶端建立連接時(shí),將該消息被設(shè)置為 true,在斷開連接時(shí),該消息被設(shè)置為 false。客戶端也可以將一條 last will 消息設(shè)置為 false,以便在連接丟失時(shí)設(shè)置該消息。代理可以保留該消息,讓新客戶端能夠讀取該主題并找到存在狀態(tài)。 如何保護(hù)通信?客戶端與代理的連接可以采用加密 TLS 連接,以保護(hù)傳輸中的數(shù)據(jù)。此外,因?yàn)?MQTT 協(xié)議對(duì)有效負(fù)載數(shù)據(jù)格式?jīng)]有任何限制,所以系統(tǒng)可以協(xié)商一種加密方法和密鑰更新機(jī)制。在這之后,有效負(fù)載中的所有內(nèi)容可以是實(shí)際 JSON 或 XML 消息的加密二進(jìn)制數(shù)據(jù)。 |