Node-RED的介紹及優點
隨著物聯網的不斷發展,各種物聯網相關的技術也在不斷發展,開源的平臺也有很多,其中就有一個特別優秀的項目,它就是Node-RED,這個項目是由IBM新興技術服務團隊構建的可視化物聯網編排工具,可基于瀏覽器的流程編輯器連接設備、服務器和 API 應用。 這句對于Node-RED的介紹是來自官方的,增加了很多概念性的詞語,這里稍作解釋一下。 首先這個項目是有IBM公司的二名研究員創建的,旨在用于快速,低成本地搭建一個Iot平臺,但后來的反正,改項目不僅僅用于構建一個物聯網平臺,還有很多用處。目前這個項目已經是OpenJS Foundation的一部分了。 此外他是一個可視化的項目,后臺使用的是NodeJS語言,提供了Web頁面,來編寫Flow, 這是改項目提供的頁面。
Node-Red的官網地址:https://nodered.org
Node-RED是一個編程工具,用于以新的有趣方式將硬件設備、API和在線服務連接在一起。
它提供了一個基于瀏覽器的編輯器,可以輕松地使用調色板中的各種節點將流連接在一起,這些節點可以一鍵部署到其運行時。
基于瀏覽器的流程編輯
Node-RED提供了一個基于瀏覽器的流量編輯器,可以輕松地使用調色板中的各種節點將流連接在一起。然后,只需單擊一下即可將流部署到運行時。
可以使用富文本編輯器在編輯器中創建JavaScript函數。
內置庫允許您保存有用的功能、模板或流程以供重復使用。
基于Node.js
輕量級運行時建立在Node.js上,充分利用其事件驅動的非阻塞模型。這使得在樹莓派等低成本硬件和云端運行成為理想的選擇。
Node的軟件包存儲庫中有超過225,000個模塊,可以輕松擴展調色板節點的范圍以添加新功能。
社會發展
在Node-RED中創建的流使用JSON存儲,JSON可以輕松導入和導出以與其他人共享。
在線流程庫允許您與世界共享您的最佳流程。
Node-Red入門使用
這里推薦使用docker運行Node-Red,有官方提供的景象,可以直接使用。當然也可以通過npm安裝的方式來安裝Node-Red。
我這里使用的是docker
- 第一步下載鏡像
docker pull nodered/node-red
- 第二步啟動鏡像
sudo docker run -it -p 1880:1880 --name=nodered --restart=always --user=root --net=host -v /data/nodered:/data -e TZ=Asia/Shanghai nodered/node-red
- 第三步打開瀏覽器訪問
訪問http://{host-ip}:1880
就能夠進入Node-RED的操作頁面了。
Node-Red運行時
打開默認帶一個comment,里面是docker運行的一些說明,大致意思就是數據會存儲在/home/user/node_red_data
文件夾里等等。
Node-RED 截止目前共有 42 個邏輯節點,按照共通、功能、網絡、序列、解析、存儲分為六大類。
所有節點都可能有左右連接點,左連接點是輸入,右連接點是輸出,特殊節點可能有多個輸入或多個輸出,其實對應代碼也不難理解,就是入參和出參。
下面依次介紹每個節點的功能。
共通
-
inject
手動輸入節點。可以定期產生一些輸入,由下一個節點消費。
當然這里是用 UI 表單配置的:
inject
之后就是消費,幾乎后面任何節點都可以消費,比如利用change
節點來設置一些環境變量時,或者利用 template
節點設置html
模版時,都可以拿到這里輸入的變量。如果在模版里,變量通過 {{msg.payload}}
訪問,如果是其它表單,甚至可以通過下拉框直接枚舉選擇。
然而這個節點往往用來設置靜態變量,更多的輸入情況是來自其它程序或者用戶的,比如http in
,這個后面會講到。其實通過這種組合關系,我們可以把任意節點的輸入從生產節點替換為inject
節點,從而實現一些 mock
效果,而inject
節點也支持配置定時自動觸發:
-
debug
調試節點,當輸出節點連接到 debug 的輸入后,將會在控制臺打印出輸出信息,方便調試。
例如:我想要每天早上六點獲取本地的天氣,我們就可以這樣寫
輸入
調試
編輯
點擊部署按鈕,之后執行inject
,就會在控制臺輸出如圖所示
- complete
監聽某些節點觸發完成動作。通過這個節點,我們可以捕獲任意節點觸發的動作,可以接入 debug 節點打印日志,或者 function 節點處理一下邏輯。 - catch
錯誤捕獲節點,當任何或指定節點觸發錯誤時輸出,輸出的格式為:
error.message 字符串錯誤消息。
error.source.id 字符串引發錯誤的節點的ID。
error.source.type 字符串引發錯誤的節點的類型。
error.source.name 字符串引發錯誤的節點的名稱。(如果已設置)
- status
監聽節點狀態變化。 - link in
只能連接link out
。link in、link out
就像一個傳送門,用來整理邏輯編排節點,使之看上去易于維護。 - link out
和link in
成對出現,用來導出輸入值,后面對接link out
可以像傳送門一樣將值傳送過去,在視覺上不會形成連接線。 - comment
注釋,配合 link 系列使用,可以讓邏輯編排 UI 更易于維護。
功能
-
function
核心的 js 函數模塊,你可以用它做很多事:
function
這里所有上級節點的值到這里都會在msg對象中,所以這里可以對msg進行處理,之后再流轉到下一個節點中。
-
switch
對應代碼的 switch,只是用起來更加方便,因為我們可以根據不同 case 導出不同的節點:
編輯switch
- change
用來改變環境變量。環境變量分為三種,分別是當前節點、流程(flow)、全局(跨應用)。也就是說,變量可以存儲在某個節點上,也可以存儲在整個畫布上,也可以跨畫布存儲在全局。
訪問參數分別為msg.
、flow.
、global.
,設置這些參數后,就像全局變量一樣,任何節點都可以在任何地方使用,比較方便。
比如應用固定了一些URL
地址,直接把一串字符串寫死在某個http in
節點里并不明智,因為后面的html
或者其它節點里可能會訪問它,一旦你進行修改,影響面會非常廣,因此最好將其設置為全局變量,在節點中通過變量方式訪問:
flow
編輯flow
這里輸入變成由流程傳入,具體的值如下圖所示。
最后輸出結果在控制臺
range
區間映射,將一個范圍的值映射到另一個范圍。其實通過 function 模塊也能完成,只是因為比較常用所以封裝了一個特殊節點。其實用戶也可以自己封裝節點,具體方式可以參考官方文檔。這里不再解釋-
template
以模版方式生成字符串或 json。
其實本質上也可以被 function 代替,只是用來寫模版的話有高亮,維護起來比較方便。
內置了 mustache 模版語法,通過 {{}} 方式使用變量。例如:
template
將流程修改為:
flow
結果輸出:
template輸出 -
delay
延遲發消息,一個快捷的工具,可以放在任何輸入與輸出中間,比如讓上面的例子中,inject
觸發后 5s 再打印結果,可以這么配置:
delay -
trigger
一個消息觸發器,相比inject
,可以更靈活的設置何時重新觸發。具體設置如下圖,設置項比inject
更靈活的多。
trigger -
exec
執行系統命令,例如,ls -A,cp -r 等,這里是運行時的操作系統命令,是極其危險的操作。例如我權限充足,執行以下操作:
exec filter
異常報告節點(Report by Exception)
網絡
網絡這里有很多種,http、socket、tcp、udp等,這里只介紹常用的http。
- http in
創建一個http
服務,可以是任何接口或者web
服務。
當你把Method
設置為post
,連接到http response
就創建了后端接口;當設置為get
請求,并連接template
寫上html
模版,并連接到http response
就創建了web
服務。這里其實就是一種BFF
的使用場景,只不過并沒有GraphQL
那種靈活度,不過可以是一種新的嘗試。
雖然這種方式創建web
服務難以使用react
或vue
框架,不過自定義節點還是為其創造了可能性,或許真的可以把前端模塊化文件定義為節點相互串聯。 - http response
http
的返回結果,只能對接http in
的輸出,總是與http in
成對使用。
如果只用了http in
但沒有用http response
,就相當于Node后端代碼里處理了請求,但是并沒有對res
做處理,所以請求會一直不中斷,知道超時為止。 - http request
與http in
創建一個http
服務不同,http request
直接發送一個網絡請求并將返回值導入到輸出節點。
序列
- split
顧名思義將一條消息處理為多條消息。 - join
將消息序列合并為一條消息。 - sort
對應代碼sort
,只能根據key
做簡單的升序降序處理,對于簡單場景比較方便,但對于復雜場景可能還會使用function
節點代替。 - batch
批量接收輸入流后,根據數量進行打包后統一輸出,等于批量打包,可以按照數量或者時間間隔進行分組。不過貌似不能像Q
或者Promise
那樣批量處理http
請求,我這里使用join
處理的http
批量請求。
批量請求
解析
其實以下的解析方法都可以用function
代替,只不過在API層面上已經封裝好了
- csv
在CSV格式的字符串及其JavaScript對象表示形式之間進行相互轉換。 - html
使用CSS選擇器從msg.payload中保存的html文檔中提取元素。 - json
在JSON字符串及其JavaScript對象表示形式之間相互轉換。 - xml
在XML字符串及其JavaScript對象表示形式之間進行相互轉換。 - yaml
在YAML格式的字符串及其JavaScript對象表示形式之間相互轉換。
存儲
- write file
將msg.payload寫入文件,添加到末尾或替換現有內容。或者,它也可以刪除文件。 - read file
以字符串或二進制緩沖區的形式讀取文件的內容。 - watch
監視目錄或文件中的更改。
總結
在使用function
函數時,還可以使用異步的方法Promise
,函數處理時會顯性的存在node
對象,在node
中會包含很多函數處理,只要最后調用node.send()
,效果與return msg
一致。并且也會顯性存在以下函數提供調用:
- Buffer - Node.js的Buffer模塊
- console - Node.js的console模塊(node.log是首選的日志方法)
- util - Node.js的util模塊
- setTimeout/clearTimeout - JavaScript的timeout函數
- setInterval/clearInterval - JavaScript的interval函數
在調研Node-Red時發現,Node-Red是一個大而全的Node框架或解決方案。就BFF而言,Node-Red與GraphQL還是存在很大差距的,總結一下幾點:
- 沒有數據模型(Scheme),或者沒法規范化的約束數據類型。這不是Node-Red的問題,是其本身并不是為BFF而生,只是其中某些特性比較像BFF而已。
- 沒有GraphQL靈活,好多不可定制化,當然Node-Red也可以使用其他NPM包來擴展,對于開源項目代碼來說,這都不是問題,但對于使用者來說成本更高。
- 對于開發者來說使用不夠方便,雖然提供了function,也暴露了幾個Node的方法,但是對于開發者來說,這顯然還不太夠。
雖然作為BFF工具來說,Node-Red并不完美,但是對于其他方面來說,他能做的事情很多。以上就是Node-Red的全部內容,有缺點和不足點評一下吧。