基於abp的小小設備控制系統設計

客戶有一堆小設備,需要通過小程式來控制它們,主要是設備門的開關、電源開關、狀態查詢、壓力控制等。下面主要紀錄下設計思路。源碼地址://gitee.com/bxjg1987/abp

最初的設計是這樣的

 

 

核心流程有3個,分別用綠、藍、黑這3種顏色來標識。

流程1:小程式端發送指令控制設備(開關、艙壓調整等)

以開關電源控制為例

  1. 小程式向wei服務端發起請求,說我想關閉設備id為1的那個設備
  2. wei服務端準備一條消息(說我要關閉id為1的那個設備),發送給RabbitMQ消息隊列
  3. RabbitMQ消息隊列將消息推送給硬體伺服器
  4. 硬體伺服器解析消息,根據設備id和按協議約定準備byte[]指令下發給具體設備
  5. 設備回復消息給硬體伺服器
  6. 硬體伺服器組織一條回復消息(所id為1的設備已經關閉成功)發送給RabbitMQ消息隊列
  7. 消息隊列將回復消息推送給web服務端
  8. web服務端通過abp提供的通知功能(默認基於a’s’p.net core signalr)通知小程式端,

此時小程式端開源認為操作成功,但是不是太準確,另一種辦法是小程式再查一次設備狀態確認下。所以上面的步驟5可以向設備觸發一個請求,讓設備立即上報一次數據。默認情況下設備是輪詢的比如30秒上報一次數據。

流程2:設備輪詢30秒上報一次數據

  1. 設備上報狀態數據
  2. 硬體伺服器將設備狀態數據存儲到資料庫
  3. 硬體伺服器向RabbitMQ消息隊列發送一條消息,說設備id為x的設備上報了狀態數據
  4. RabbitMQ消息隊列將消息推送給web服務端
  5. web服務端通過abp提供的通知機制通知小程式端

步驟3沒必要直接將狀態數據推送給消息隊列,因為此消息的接收方未必關係具體的數據,目前設計只是說有設備狀態上報了,這個消息通知到接收方,由接收方決定是否主動來查設備狀態

流程3:小程式主動查詢設備狀態

這個就比較簡單了

  1. 小程式端向web服務端發起查詢請求
  2. web伺服器直接從資料庫查詢設備狀態返回就可以了

有點問題,這樣查詢不是設備的當前狀態,我們可以再定義介面直接去查一次當前設備的狀態,但是這樣編碼比較大,也不利於我們復用現有流程。最簡單的辦法是定義一個介面,向設備發送一條指令說請你立即上報一次數據,小程式原有的查詢設備狀態查到就是最新的了。

設備服務端SuperSocket

開源地址://github.com/kerryjiang/SuperSocket,這是個設計得比較好的,基於.net core的socket的通訊框架。官方有文檔學起來比較簡單。

它負責與設備通訊,可以單獨部署在一台伺服器上。

基於Abp的Web服務端

這就不多說了,因為它已經為我們提供了很好的web服務端基礎設施,免得從頭做起。此服務端也可以單獨部署一台伺服器

消息隊列RabbitMQ

其它mq沒用過,就用它咯。它主要是解耦設備服務端和web服務端的,主要是它可以主動推送消息給接收方,也可以考慮使用redis的推送來實現。消息隊列也可以單獨部署一台伺服器

簡化後的設計

如果設備比較少,請求量不大可以用下面這種簡化的設計

 

既然是簡化,流程就不說了。主要是省略了消息隊列,並且省略了指令回復的處理,而是使用輪詢的方式,比如每過10秒查一次當前設備狀態,控制設備時,只是下髮指令,而不等結果,因為我們的輪詢會查到下一次的設備狀態。

這裡有些注意:

  • 設備上報狀態存入資料庫時可以使用一個全局的資料庫連接
  • web伺服器向設備伺服器發送指令時也可以考慮使用全局的tcp連接
  • web伺服器向設備伺服器發送指令時可以使用supersocket提供的客戶端庫

結束

簡化後的方案最low,但是也最容易實現,目前源碼中就是採用的這種方式。前一種方式稍微好點,3台伺服器可以分開部署,如果並發再大點可以考慮下分散式了,再不行就放棄這個上思路,直接上個阿里雲IOT啥的。