物聯(lián)網(wǎng)網(wǎng)關(guān)開發(fā):基于MQTT消息總線的設(shè)計(jì)過(guò)程
MQTT網(wǎng)關(guān)的作用
MQTT物聯(lián)網(wǎng)這個(gè)詞語(yǔ)的范疇太廣,似乎所有的硬件設(shè)備,只要能夠接入網(wǎng)絡(luò),就可以稱之為物聯(lián)網(wǎng)產(chǎn)品,似乎物聯(lián)網(wǎng)這個(gè)詞可以把一切都納入到其中。
這么空洞的詞語(yǔ)不利于我們的講解,因此我們就用一個(gè)可以感知、想象的場(chǎng)景來(lái)代替,那就是智能家居系統(tǒng),這是物聯(lián)網(wǎng)時(shí)代的典型產(chǎn)品了。
1.指令轉(zhuǎn)發(fā)
在一個(gè)智能家居系統(tǒng)中,假設(shè)有這么幾個(gè)設(shè)備:紅外感應(yīng)、門磁、插座、排插、聲光報(bào)警器、燈泡。
這些設(shè)備的通信模塊,如果是 WiFi 或者是藍(lán)牙,那么一般都可以直接通過(guò)手機(jī)來(lái)控制(當(dāng)然,需要廠家提供相應(yīng)的手機(jī) APP),手機(jī)就相當(dāng)于一個(gè)中心節(jié)點(diǎn),控制著所有的設(shè)備。
目前市面上的一些智能設(shè)備單品都是這樣的通信方式,例如:空調(diào)、吸塵器、空氣凈化器、冰箱等等。只要在這些設(shè)備中加一個(gè)無(wú)線通信模塊即可(例如:ESP8266模塊)。
如果通信模塊是其它的通信模塊,例如:RF433、ZigBee、ZWave等,由于手機(jī)沒(méi)有這些通信模塊,因此就需要一個(gè)網(wǎng)關(guān)來(lái)“轉(zhuǎn)發(fā)”指令。
手機(jī)和網(wǎng)關(guān)都連接到家中的路由器,處于同一個(gè)局域網(wǎng)中,手機(jī)把控制指令發(fā)送給網(wǎng)關(guān),網(wǎng)關(guān)再把指令轉(zhuǎn)發(fā)給相應(yīng)的設(shè)備。
2.外網(wǎng)通信
在上面的通信模型中,手機(jī)和網(wǎng)關(guān)由于處于同一個(gè)局域網(wǎng)中,因此可以直接通信。如果手機(jī)不在局域網(wǎng)中呢?那么就要通過(guò)云端的服務(wù)器來(lái)轉(zhuǎn)發(fā)了,通信模型如下:
手機(jī)把指令發(fā)到服務(wù)器;
服務(wù)器把指令轉(zhuǎn)發(fā)給網(wǎng)關(guān);
網(wǎng)關(guān)把指令發(fā)給指定的設(shè)備;
以上是控制指令的流程,如果是設(shè)備發(fā)出的報(bào)警信息呢,數(shù)據(jù)的流向就是反向進(jìn)行的。
可以看出,網(wǎng)關(guān)是所有設(shè)備之間通信的中心節(jié)點(diǎn),也是內(nèi)網(wǎng)與外網(wǎng)之間通信的中轉(zhuǎn)節(jié)點(diǎn),也就是把各種智能設(shè)備連接到互聯(lián)網(wǎng)的中轉(zhuǎn)器。
3.協(xié)議轉(zhuǎn)換
上面已經(jīng)提到,硬件設(shè)備上的通信模塊都是確定的(RF,ZigBee,ZWave等等),一般來(lái)說(shuō),可以把這些通信模塊稱呼為無(wú)線通信協(xié)議。在一套智能家居系統(tǒng)中,所有設(shè)備的無(wú)線通信協(xié)議大部分都是相同的。
那么,不同類型的無(wú)線通信協(xié)議設(shè)備是否可以共存在同一個(gè)系統(tǒng)中呢?
答案是:可以。只要在網(wǎng)關(guān)中,集成了相應(yīng)的無(wú)線通信協(xié)議模塊就可以達(dá)到這個(gè)目的!
從手機(jī)APP上看,所有的設(shè)備都是相同的,不會(huì)關(guān)心設(shè)備的無(wú)線通信協(xié)議是什么,因此,發(fā)出的控制指令都是協(xié)議無(wú)關(guān)的。
當(dāng)網(wǎng)關(guān)接收到控制指令時(shí),首先根據(jù)指令內(nèi)容查找出目標(biāo)設(shè)備,然后確定目標(biāo)設(shè)備的無(wú)線通信協(xié)議,后把指令發(fā)送給對(duì)應(yīng)的硬件通信模塊,由該通信模塊通過(guò)無(wú)線電信號(hào)把控制指令發(fā)送到設(shè)備。
從這個(gè)指令的傳輸過(guò)程來(lái)看,網(wǎng)關(guān)就充當(dāng)著協(xié)議轉(zhuǎn)換的角色。
另外還有一種通信場(chǎng)景:當(dāng)系統(tǒng)中的一個(gè)“輸入”設(shè)備與一個(gè)“輸出”設(shè)備進(jìn)行綁定/關(guān)聯(lián)時(shí),例如:
(1)紅外感應(yīng)器與聲光報(bào)警器綁定:當(dāng)紅外感應(yīng)器監(jiān)測(cè)到人體時(shí),發(fā)出信號(hào),然后控制聲光報(bào)警器發(fā)出報(bào)警;
(2)門磁與燈綁定:當(dāng)開門時(shí),門磁發(fā)出信號(hào),自動(dòng)打開燈光;
如果“輸入”設(shè)備與“輸出”設(shè)備是不同類型的無(wú)線通信協(xié)議,也需要網(wǎng)關(guān)來(lái)進(jìn)行協(xié)議轉(zhuǎn)換。

4.設(shè)備管理
在一個(gè)智能家居系統(tǒng)中,設(shè)備可多可少,對(duì)這些設(shè)備進(jìn)行管理也是很重要的事情。網(wǎng)關(guān)作為系統(tǒng)的中心節(jié)點(diǎn),對(duì)設(shè)備進(jìn)行管理的重任理所當(dāng)然就由網(wǎng)關(guān)來(lái)承擔(dān)。
設(shè)備管理功能包括:
設(shè)備的添加和刪除;
設(shè)備狀態(tài)的管理(電量、設(shè)備斷網(wǎng)、失聯(lián)等等);設(shè)備樹的管理;
邊沿計(jì)算(自動(dòng)化控制)
在正常的情況下,網(wǎng)關(guān)是可以通過(guò)路由器,與服務(wù)器保持著長(zhǎng)連接的。如果服務(wù)器的處理能力比較強(qiáng)大,智能家居系統(tǒng)中所有需要處理的事情都可以丟給服務(wù)器來(lái)計(jì)算、處理,服務(wù)器在計(jì)算之后把處理結(jié)果再發(fā)送給網(wǎng)關(guān)??雌饋?lái)想法很完美!
但是,考慮下面這 2 種情況:
路由器出現(xiàn)問(wèn)題了,網(wǎng)關(guān)無(wú)法連接到服務(wù)器,因此就無(wú)法把本地?cái)?shù)據(jù)及時(shí)上報(bào);
系統(tǒng)中出現(xiàn)了異常情況,需要緊急處理,如果把信息上報(bào)到服務(wù)器,由服務(wù)器計(jì)算之后再回傳給網(wǎng)關(guān),耗費(fèi)的時(shí)間可能超過(guò)了可容忍時(shí)間,該如何處理?(可以用車聯(lián)網(wǎng)系統(tǒng)來(lái)腦補(bǔ)一下這個(gè)場(chǎng)景:自動(dòng)駕駛中的汽車遇到緊急情況,如果把所有信息上傳給服務(wù)器,然后等待服務(wù)器的下一步指令?)
對(duì)于上面的這些場(chǎng)景,把一些計(jì)算、處理操作放在網(wǎng)關(guān)這一端來(lái)處理也許更合適!這也是近幾年比較流行的邊沿計(jì)算。
(1)邊緣計(jì)算,是指在靠近物或數(shù)據(jù)源頭的一側(cè),采用網(wǎng)絡(luò)、計(jì)算、存儲(chǔ)、應(yīng)用能力為一體的開放平臺(tái),就近提供近端服務(wù)。
(2)其應(yīng)用程序在邊緣側(cè)發(fā)起,產(chǎn)生更快的網(wǎng)絡(luò)服務(wù)響應(yīng),滿足行業(yè)在實(shí)時(shí)業(yè)務(wù)、應(yīng)用智能、安全與隱私保護(hù)等方面的基本需求。
(3)邊緣計(jì)算處于物理實(shí)體和工業(yè)連接之間,或處于物理實(shí)體的頂端。而云端計(jì)算,仍然可以訪問(wèn)邊緣計(jì)算的歷史數(shù)據(jù)
網(wǎng)關(guān)內(nèi)部進(jìn)程之間的通信
在設(shè)計(jì)一個(gè)應(yīng)用程序的架構(gòu)時(shí),可以通過(guò)多線程來(lái)實(shí)現(xiàn),也可以通過(guò)多進(jìn)程來(lái)實(shí)現(xiàn),每個(gè)人的習(xí)慣都不一樣,各有各的好處。我們這里不去討論孰優(yōu)孰劣,因?yàn)槲覍?duì)多進(jìn)程這樣的設(shè)計(jì)思想比較偏愛(ài),所以就直接按照多進(jìn)程的程序架構(gòu)來(lái)討論。
5.網(wǎng)關(guān)中需要哪些進(jìn)程
網(wǎng)關(guān)中需要執(zhí)行的所有進(jìn)程,是根據(jù)網(wǎng)關(guān)的功能來(lái)決定的,假設(shè)包括如下的功能:
(1)連接外網(wǎng)的進(jìn)程 Proc_Bridge
網(wǎng)關(guān)需要連接到云端的服務(wù)器,需要一個(gè)進(jìn)程與服務(wù)器之間保持長(zhǎng)連接,這樣就可以及時(shí)接收到服務(wù)器發(fā)來(lái)的控制指令,以及把系統(tǒng)內(nèi)部數(shù)據(jù)及時(shí)上報(bào)給服務(wù)器。
這個(gè)進(jìn)程需要把從服務(wù)器接收到的指令轉(zhuǎn)發(fā)到網(wǎng)關(guān)系統(tǒng)內(nèi)部,把從系統(tǒng)內(nèi)部接收到的信息轉(zhuǎn)發(fā)給服務(wù)器,類似于橋接的功能,因此命名為 Proc_Bridge。
(2)設(shè)備管理進(jìn)程 Proc_DevMgr
這個(gè)進(jìn)程用來(lái)執(zhí)行設(shè)備管理功能,設(shè)備的添加(入網(wǎng))、刪除(退網(wǎng)),都由此進(jìn)程來(lái)管理。
(3)協(xié)議轉(zhuǎn)換進(jìn)程 Proc_Protocol
下行:把應(yīng)用層的統(tǒng)一通信協(xié)議,轉(zhuǎn)換成不同類型無(wú)線通信協(xié)議,發(fā)送給相應(yīng)的無(wú)線模塊。
上行:把設(shè)備上報(bào)的、不同類型的無(wú)線通信協(xié)議,轉(zhuǎn)換成應(yīng)用層的統(tǒng)一通信協(xié)議。
(4)邊沿計(jì)算進(jìn)程(自動(dòng)化控制) Proc_Auto
很明顯,這需要一個(gè)進(jìn)程來(lái)處理各種計(jì)算,這個(gè)進(jìn)程就相當(dāng)于系統(tǒng)的大腦。
(5)無(wú)線通信協(xié)議相關(guān)的進(jìn)程 Proc_ZigBee, Proc_RF, Proc_ZWave
在硬件上,每一種無(wú)線通信模塊通過(guò)串口或其他硬件連接方式與到網(wǎng)關(guān)的 CPU 進(jìn)行通信,因此,每一種無(wú)線通信模塊都需要一個(gè)相應(yīng)的進(jìn)程來(lái)處理。
(6)其他“軟設(shè)備”進(jìn)程 Proc_Xxx
在之前的項(xiàng)目中,還遇到一些硬件設(shè)備,它們與門磁、插座等設(shè)備在邏輯上處于同一個(gè)層次,但是與網(wǎng)關(guān)之間是通過(guò) TCP 來(lái)連接。對(duì)于這樣的設(shè)備,也可以使用一個(gè)進(jìn)程來(lái)進(jìn)行管理。
MQTT消息總線
以上這些進(jìn)程之間需要相互通信,不是簡(jiǎn)單的點(diǎn)對(duì)點(diǎn)通信,而是一個(gè)網(wǎng)狀的通信模型。比如:
設(shè)備管理進(jìn)程 Proc_DevMgr:當(dāng)任何一種設(shè)備被添加到系統(tǒng)中時(shí),都需要處進(jìn)行處理,因此它需要與 Proc_ZigBee, Proc_RF, Proc_ZWave 這些進(jìn)程進(jìn)行通信;
當(dāng)某個(gè)設(shè)備上報(bào)數(shù)據(jù)時(shí)(例如:Proc_ZigBee),Proc_Protocol 進(jìn)程需要把數(shù)據(jù)進(jìn)行協(xié)議轉(zhuǎn)換,然后 Proc_Bridge 進(jìn)程把轉(zhuǎn)換后的數(shù)據(jù)上報(bào)給服務(wù)器,同時(shí) Proc_Auto 進(jìn)程需要檢查這個(gè)設(shè)備上報(bào)的數(shù)據(jù)是否觸發(fā)了其他相關(guān)聯(lián)的設(shè)備;
也就是說(shuō),這些進(jìn)程中間的通信是相互交叉的,如果通過(guò)傳統(tǒng)的 IPC 方式(共享內(nèi)存、命名管道、消息隊(duì)列、Socket)等,處理起來(lái)比較復(fù)雜。
引入了 MQTT 消息總線之后,每個(gè)進(jìn)程只需要掛載到總線上。每個(gè)進(jìn)程只需要聽自己感興趣的 topic,就可以接收到相應(yīng)的數(shù)據(jù)。
6.網(wǎng)關(guān)與云平臺(tái)之間的通信
上面講解的設(shè)計(jì)過(guò)程,是網(wǎng)關(guān)內(nèi)部的各功能模塊之間通信方式,這也是我們作為嵌入式開發(fā)者能充分發(fā)揮的部分。
網(wǎng)關(guān)與云平臺(tái)之間的通信方式一般都是客戶指定的,就那么幾種(阿里云、華為云、騰訊云、亞馬遜AWS平臺(tái))。一般都要求網(wǎng)關(guān)與云平臺(tái)之間處于長(zhǎng)連接的狀態(tài),這樣云端的各種指令就可以隨時(shí)發(fā)送到網(wǎng)關(guān)。
當(dāng)然了,這些云平臺(tái)都會(huì)提供相應(yīng)的 SDK 開發(fā)包,一般使用的 MQTT 協(xié)議來(lái)連接云平臺(tái)更多一些。在一些文檔中,會(huì)把位于云端的 MQTT 服務(wù)器稱作 Broker,其實(shí)就是一個(gè)服務(wù)器。
進(jìn)程 Proc_Bridge 的功能主要有 2 點(diǎn):
(1)與云平臺(tái)的數(shù)據(jù)傳輸通道;
(2)協(xié)議轉(zhuǎn)換:把云平臺(tái)相關(guān)的協(xié)議轉(zhuǎn)換成網(wǎng)關(guān)內(nèi)部的協(xié)議,以及相反的轉(zhuǎn)換。
也就是說(shuō):Proc_Bridge 進(jìn)程需要同時(shí)連接到云平臺(tái)的 MQTT Broker 和網(wǎng)關(guān)內(nèi)部的 MQTT 消息總線。在下一篇文章中,我們來(lái)專門講解這部分的內(nèi)容,并提供一個(gè)實(shí)現(xiàn)橋接功能的代碼模板。