蘆晨博
(沈陽工業大學 信息科學與工程學院,沈陽 110870)
在基于Z-Stack 協議棧的ZigBee 網絡中通過使用16 位短地址[1]在本地網絡中標識設備和在網絡中發送數據,當一個節點加入網絡的時候將由它的父節點給它分配短地址[2].這個短地址的長度規定了在一個ZigBee 網絡中最多能搭載65 535 個節點,而在實際應用中由于ZigBee 節點芯片的運算能力有限,加上載波偵聽多路訪問/沖突避免[3](Carrier Sense Multiple Access with Collision Detection,CSMA/CA)等原因很難達到上萬節點的掛載.在使用全路由節點網絡[4,5],更強性能的協調器或多信道通訊等手段時雖然可有效提高網絡中的節點數量,仍然無法突破短地址帶來的上限,同時又大大增加了系統復雜度.在物聯網蓬勃發展的今天與萬物皆可互聯的理念下[6],搭建能夠處理大量節點的網絡結構意義重大.
本文通過在ZigBee 節點網絡之上利用互聯網服務器搭建外網結構,集中管理各個內網ZigBee 節點群,并提供自組網功能.根據實際業務需求進行節點網絡的組建,服務端將集中管理所有節點數據并對外提供Web 服務.在服務端的架構設計上可采用分布式,搭建集群,負載均衡等多種應對高并發[7,8]的設計方式,使得系統性能與節點掛載能力獲得極大提升.
系統整體由終端節點,節點協調器,內網控制器,中央服務器,人機接口構成五層網絡結構.
終端節點、協調器、內網控制器組成內網結構.其中ZigBee 終端節點可掛載各類傳感器和控制設備與ZigBee 協調器之間通過利用Z-Stack 協議棧完成自組網與無線通訊功能.每個獨立的ZigBee 網絡都配有一臺直接與外網相連并具有一定存儲功能的內網控制器.協調器與內網控制器可通過串口相連或直接集成在一起.控制器接受中央服務器的指令信息來驅動ZigBee 協調器,并通過廣播的方式向終端節點傳遞指令消息,同時將終端的狀態信息同步至中央服務器.
中央服務器內維護著各個內網系統控制器的IP地址和與之相匹配的身份標識.整個系統中每一個終端節點擁有一個唯一的全局節點ID(GlobalID),服務器通過GlobalID 和控制器IP 地址可對指定節點發送控制信息.中央數據庫內存儲著所有節點的狀態信息并可提供Web 服務供用戶客戶端訪問.整體結構如圖1.
任意一個內網結構中,每個終端節點在啟動之前會被分配一個身份標識符(NodeID).啟動設備后在ZStack 協議棧的幫助下會自動尋找當前網絡內的協調器,若匹配成功則加入該網絡.在完成自組網工作后節點進入正常工作狀態.終端節點除自組網任務外仍需在Z-Stack 協議棧操作系統抽象層(Operating System Abstraction Layer,OSAL)[9]中注冊和初始化兩項基本任務.

圖1 整體機構示意圖
(1)狀態信息定時發送任務:終端節點周期性的向網絡內的協調器發送狀態信息其目的是為了表明自身存活狀態并可傳遞各類傳感器信息.數據格式一般為:NodeID+狀態信息.
(2)指令消息接受任務:系統中協調器以廣播的形式傳遞消息,數據格式為:NodeID+操作碼,當終端指令與指令消息中的NodeID 對比成功后執行操作碼對應的自定義任務,對比失敗則忽略消息.
系統中ZigBee 協調器除完成自組網任務外,僅作為消息的傳遞者.將內網控制器傳來并將受到的終端節點狀態信息傳遞給內網控制器.
內網控制器是連接ZigBee 網絡與中央服務器的核心樞紐,用于解析服務端請求,向協調器發送指令信息和封裝節點狀態信息同步至中央服務器.控制器會被分配一個公網IP 地址供中央服務器查找.在本文的設計中控制器需至少包含四項基本任務:
(1)中央服務器消息監聽任務(CenterMsgListener):啟動一個SocketService 監聽指定端口,中央服務器會向該端口發送各類指令信息,調用MsgParser 解析指令消息,其中數據段的格式為GlobalID(全局節點ID)的指令消息原封不動通過廣播方式發送出去.
(2)中央服務器消息發送任務(CenterMsgSender):新建SocketClient 向中央服務器發送包括控制器心跳、注冊信息、節點狀態的更新、新節點入網與節點失活等多種消息.
(3)協調器消息監聽任務(ZNodeMsgListener):接收協調器收集到的終點節點狀態信息.
(4)協調器消息發送任務(ZNodeSender):向協調器發送正確格式的指令字符.在控制器初始化階段還需加載4 張基本數據表.

表1 控制器初始化基本數據表
2.3.1 處理服務器控制信息
當控制器接收到中央服務器的指令消息時需依次執行以下任務:
(1)解析消息獲取指令數據段,解析失敗向服務器返回ERROR-指令消息非法.
(2)查詢Global2Node 獲取內網節點ID,獲取失敗時向服務端返回EXCEPTION-節點不存在或已下線.
(3)對照Command 表封裝正確格式的指令信息.
(4)獲取ZNodeSender 向協調器發送指令消息字符,若發送失敗向服務端返ERROR (節點操作失敗).
(5)向服務端返回SUCCESS.
(6)更新NodeStatus 表中的狀態信息.
(7)在本地磁盤內新增操作記錄與日志信息.
2.3.2 處理協調器節點消息
控制器接收到協調器節點心跳信息時需根據內容作出不同的處理,當某一節點的心跳消息第一次出現時需在本地緩存節點狀態信息,為減輕服務器端的壓力只有在節點狀態發生實質上的變化時才會發送更新消息.具體處理流程如圖2所示.
2.3.3 處理節點離線
Status 中記錄著對應節點的上次心跳時間,控制器初始化完成后啟動監聽線程周期性的遍歷NodeStatus表,根據當前時間戳查找已超時節點,封裝超時節點信息向服務端發送節點下線消息,清除NodeStatus 中緩存的對應節點記錄,更新本地數據庫.
中央服務器是外網結構的核心,其核心功能主要分為三部分:
(1)維護各個內網控制器的通訊地址與通訊方式,快速匹配目標節點發送控制信息.
(2)響應并處理控制器請求,存儲所有節點狀態信息,維護系統內數據的一致性.
(3)對外提供Web 服務,將對ZigBee 節點的操作抽象成具體業務功能.外網結構如圖3所示.
對于客戶端來說,所有被查詢的節點數據均來自于中央數據庫,在享受這種高效的,體驗良好的查詢服務時,需要重點關注數據實時性的問題.系統內影響實時性的主要因素來源于從節點狀態發生變化到數據庫更新所產生的時間差.
針對此問題在內網結構中可以選擇提高心跳信息的采集頻率、使用更高性能的網絡模塊、在終端節點上采用中斷的方式提交更新數據或者可以在同一業務區域內搭建多個內網結構.更高的實時性必然需要付出更多的成本和性能.對于中央服務器而言并不需要過多的關心業務,最重要的是盡可能的提高處理并發的能力.除了在請求處理上采用合理的負載均衡策略外,值得一提的是在節點ID 字段的分配時可在其中加入業務地區與業務類型的標識字符,這種設計在存儲時十分有利于做分庫分表[10],在查詢時也可根據ID 中的標識字符定位數據庫的位置.性能提高十分明顯.

圖2 節點信息處理流程圖

圖3 外網結構示意圖
當服務器接受到節點操作請求時,為保證節點操作的準確性與系統內數據的一致性,用戶的請求與中央服務器對控制器的操作請求都應該是阻塞的,核心數據的事務[11]應包含整個過程.
在控制器初始化階段控制器需向中央服務器發送注冊信息表明身份請求接入網絡.數據段中至少包括:自身IP 地址,用于接受消息的端口號與通訊的使用密鑰.
其中密鑰為中央服務器與控制器之間約定的加密與解密字符,為保證通訊的安全每一次消息的傳遞都應使用密鑰,出于對時效性與安全性的考慮還在加密字段中加入了時間戳,在加密與解密的兩次結果中時間間隔過長也應視為異常信息.
當控制器第一次注冊時(即服務器內沒有該控制器記錄)視為新入網控制器.中央服務器會為其分配一個ID 響應給控制器,同時在中央數據庫生成連接記錄,并將該控制器加入心跳監聽序列中.
當注冊完成后控制器陸續會將它所在內網中新加入的ZigBee 節點信息發送至服務器,此時消息數據段中包括控制器ID 節點GlobalID 和節點信息.在服務器將新增ZigBee 節點的數據同步完成后該網絡內的節點即可正常使用.
順利完成第一次注冊后控制器會在本地持久化控制器ID,當控制器重新啟動再次進行注冊任務時會攜帶控制器ID 表明身份重新激活網絡連接.當控制器各項信息需要更新時便可使用重新注冊的方式.
控制器注冊完成之后會周期性的向中央服務器發送心跳包,服務器會集中管理并監聽所有ZigBee 網絡的心跳[12].本文的設計中使用了redis[13,14]中SortedSet結構集中管理心跳記錄,成員分數為最近一次心跳的時間戳.當集合中成員數量大于64 時SortedSet 同時使用了Hash 和Skiplist[15]兩種設計實現,其范圍查找操作復雜度一般為O(log(N)+M)(N為有序集的基數,M為被結果集的基數).使用范圍查找在集合中成員分數小于當前時間戳與約定超時時間的差所產生的結果集即可認為是心跳已超時的連接.服務端將會對結果集內的控制器發送存活確認消息,當消息響應異常時可視為連接中斷,更改控制器及屬于該控制器網絡中所有節點的連接狀態并執行相應的離線異常處理機制.
系統內針對用戶的查詢與控制操作都通過訪問中央服務器所提供的Web 服務實現.用戶可通過使用瀏覽器或手機app 等多種互聯網手段向服務器發送請求,服務端最終會將用戶的行為翻譯成節點GlobalID 與操作碼的形式.通過GlobalID 查詢數據庫,如果是控制信息將獲取節點所在內網的IP 地址,再由服務端與指定的ZigBee 網絡進行通訊.
為驗證系統可行性,利用有限的硬件資源搭建如下測試系統:
系統中央服務器采用阿里云輕量級應用服務器:1 核CPU、2 GB 內存、40 GB 固態硬盤、峰值帶寬1 Mbps、操作系統為CentOS 7.3 版本、提供獨立公網IP 與域名解析功能.在服務器內使用Redis 3.0 搭配MySQL 5.7 版本作為系統中央數據庫.后端代碼主要由Java 語言編寫,所有針對處理用戶http 請求的服務均使用了Tomcat 服務器.網站的入口使用Nginx 作為反向代理服務器用于匹配并分發不同類型的請求.
內網控制器由Java 語言編寫,并只依賴于Java 虛擬機,便于移植.為驗證存在多個內網控制器時系統的運行狀態,使用VMware 啟動10 臺虛擬機作為內網控制器,運行環境為CentOS7.3,利用花生殼內網穿透、端口映射軟件將10 臺虛擬機與公網相連.個人電腦與協調器通過串口相連,為解決多個虛擬機無法同時訪問一個串口的問題,編寫腳本進行串口收發再與虛擬機進行通訊起到模擬相連的作用.雖然多個控制器是與同一個ZigBee 網絡相連,但由于相互之間網絡地址不同,數據也不同步,即可視為多個網絡.
系統中協調器與終端均使用CC2530 芯片,協議棧版本為TI-Z-Stack 2007.網絡內有一個協調器搭配37 枚終端,部分終端搭載了超聲波傳感器或溫濕度傳感器.
在整個測試過程中,系統能夠自行處理任意ZigBee 節點層面和內網控制器層面的接入與離線情況,運行穩定魯棒性強.通過訪問中
央服務器可實時查詢任意節點上傳感器的測量值,針對不同內網之間實際相同節點的數據查詢極少出現不同步狀況.通過http 請求的方式對節點上LED 小燈的控制信息在當前測試環境下操作延遲一般在3 秒內即可完成響應,當對于任意一個網絡內的節點下達控制信息后,其余9 個網絡中的節點信息均能在不超過兩個節點心跳的時間內同步至中央服務器.
本文提出一種通過搭建互聯網服務器的方式來集中管理多個ZigBee 網絡的設計方案.所有節點的數據集中存儲便于訪問,同時可對系統內任意節點實現精準控制與狀態信息的獲取.各個ZigBee 網絡之間的設計不存在耦合,在不同業務背景下應用時不需要更改底層實現,系統擴展性強.接下來的工作中需重點關注ZigBee 網絡中對控制指令執行的可靠性問題,完善各類異常處理機制.并針對系統各個模塊的性能進行更多的測試工作.