Node-RED是一个物联网可视化编程工具
Node-RED是一种基于流程的编程工具,由IBM的新兴技术服务团队原创开发,现在归属于JS 基金会。
流程化编程模式最初是由J. Paul Morrison在20世纪70年代发明的,它将程序的行为表示为一个由黑箱组成的网络,也就是我们在Node-RED中所说的“节点”。每个节点都有其明确的功能目标,为此,我们要向它提供数据,由它对数据进行处理,并将结果发送出去。而网络则负责控制数据在节点间的流动。
如果把它以视觉化模型的形式表示,那么就能被更大范围的用户所接受和理解。只要我们能将问题分解为多个单独的步骤,那么就可以将其表示为流程化模型。这样,即便对各个节点内部的代码不了解,也能对问题的处理过程有个直观的把握。
Node-RED由基于Node.js的运行时环境组成,当你将Web浏览器指向它时,就可以访问到流程编辑器。在浏览器中,我们以拖拽和连线的方式创建应用程序,也就是将所需的节点从面板拖拽到工作区中,然后用连线将它们连接到一起。然后通过一键部署方式,我们又将开发好的应用部署到运行时中,在那里它被运行起来。
利用社区开发的新类型节点,可以很容易地对节点面板进行扩展,同时,用户所创建的流程也很容易以JSON文件形式分享。
Node-RED诞生于2013年,其开发者为IBM新兴技术服务组的Nick O’Leary和Dave Conway-Jones,当初仅仅是两个人的副业项目。
最初的开发目的是为了从概念上验证MQTT主题间映射的视觉化表示和处理方式,但很快地,就变成了一个非常通用的开发工具,而且很容易地扩展到了其他应用领域。
2013年9月起,Node-RED就成为开源项目,并且一直以开放的方式进行开发,最终在2016年10月,成为了JS基金会资助的项目。
更多细节参见:
关于转入JS基金会的博客文章。
Nick在Monki Gras 2016上的演讲:
我们建议使用6.x LTS或6.x版的Node.js,因为Node-RED不再支持0.10.x或0.12.x版本。
注意: 由于Node.js 7.x仍在开发过程中,因此不建议将其作为Node-RED的底层环境。另外,很多第三方Node软件包(特别是那些含有二进制组件的)可能对Node 7.x以上版本支持的也不是很好,如果自己搞不定,请尽量与软件包的原作者联系。
你可以从以下地方获得最新的Node 6.x
长效版(LTS):
Max OS X 安装工具: Universal
Windows 安装工具: 32-bit or 64-bit
Linux 二进制包: 32-bit or 64-bit
使用与操作系统匹配的打包版本通常是最便捷的一种做法。
另外,对于某些特定的硬件平台,我们还提供了专门的说明:
树莓派
BeagleBone Black
此处还有其他可用的下载资源。
安装Node-RED的最简单方式就是,使用Node的软件包管理工具npm。将其作为一个全局模块安装时,执行命令node-red
将会被加入到系统路径中:
sudo npm install -g --unsafe-perm node-red
注意: 千万不要用 npm 1.x
安装Node-RED,应该先执行:sudo npm install -g [email protected]
将其升级到最新的 npm 2.x
版。
注意: sudo
是Linux或OS X系统的非root用户在执行命令时需要加入的。如果你的系统是Windows,那么就不需要在命令中加入sudo
,但是必须要以系统管理员身份执行这些命令行指令。
注意: 在安装过程中,有可能会出现一些node-gyp
错误提示,这些大多是典型的非致命性错误, 一般与一些要求编译的可选依赖项有关。Node-RED的运行一般不需要这些可选的依赖项,但如果你发现一些附加的Node模块需要编译功能的话,你可以参考一下这里的node-gyp
安装方法。
安装完成后,就可以运行Node-RED了。
可以从这里下载最新的发行版压缩文件, 其中包含一个名为node-red-X.Y.Z
的目录,X.Y.Z
表示版本号。 将其解压后,进入这个目录并执行以下命令:
npm install --production
对于那些愿意使用开发代码的用户,或者是期望贡献代码的开发者,可以从Github获取代码并执行。
你可以直接复制Github上的源代码库:
git clone https://github.com/node-red/node-red.git
复制好后,必须先安装一些必要的核心模块:
cd node-red npm install
注意: 当运行从git仓库获取的复制代码时,必须要安装所有的依赖项,而不仅仅是与生产有关的部分,因此不能在命令中使用--production
选项。
为了在使用前编译应用,还必须以全局方式安装grunt-cli
。
sudo npm install -g grunt-cli
然后编译并运行整个应用
grunt build node red
安装完成后,就可以运行Node-RED了。
如果Node-RED是以全局npm软件包方式进行安装的,那么就直接执行命令node-red
:
$ node-red Welcome to Node-RED =================== 25 Feb 22:51:09 - [info] Node-RED version: v0.14.6 25 Feb 22:51:09 - [info] Node.js version: v4.6.0 25 Feb 22:51:09 - [info] Loading palette nodes 25 Feb 22:51:10 - [warn] ------------------------------------------ 25 Feb 22:51:10 - [warn] [rpi-gpio] Info : Ignoring Raspberry Pi specific node 25 Feb 22:51:10 - [warn] ------------------------------------------ 25 Feb 22:51:10 - [info] Settings file : /home/nol/.node-red/settings.js 25 Feb 22:51:10 - [info] User Directory : /home/nol/.node-red 25 Feb 22:51:10 - [info] Server now running at http://127.0.0.1:1880/ 25 Feb 22:51:10 - [info] Creating new flows file : flows_noltop.json 25 Feb 22:51:10 - [info] Starting flows 25 Feb 22:51:10 - [info] Started flows
这样,你就可以在http://localhost:1880上看到Node-RED编辑器了。
对于某些特殊的硬件平台,我们还提供了一些专门的说明:
树莓派
BeagleBone Black
现在,你可以来建立你的第一个流程了。
即便Node-RED不是以全局方式安装的,依然想通过node-red
指令执行。
如果安装方式为npm,那么启动脚本就是,你执行npm install
命令时所在文件夹下的node_modules/node-red/bin/node-red
。如果安装方式为zip文件,那么脚本就是解压文件夹中的node-red-X.Y.Z/bin/node-red
。
首先,要让node-red
脚本成为可执行文件:
chmod +x/bin/node-red
然后,你可以利用一下方式启动Node-RED:
/bin/node-red
对于Windows,要在执行npm install
命令或解压zip文件的目录中,执行:
node node_modules/node-red/red.js
Usage: node-red [-v] [-?] [--settings settings.js] [--userDir DIR] [flows.json] Options: -s, --settings FILE use specified settings file -u, --userDir DIR use specified user directory -v enable verbose output -?, --help show usage
By default, Node-RED stores your data in the directory默认情况下,Node-RED将用户数据保存在$HOME/.node-red
目录中。出于向后兼容的原因,如果Node-RED在安装目录中检测到了用户数据,也将会替代使用。在升级文档中,专门有一个部分是关于如何将数据从Node-RED安装目录中移植出来的。
如果想替代默认使用的目录,可以通过添加命令行参数--userDir
实现。
在某些场合,我们需要向底层的Node.js进程传递参数。比如当它运行在像树莓派或者BeagleBone Black这类内存受限这样的设备上时,
为了做到这点,你必须以node-red-pi
方式启动node-red
中的脚本。 注意:这个脚本无法在Windows上使用。
另外,也可以通过node
指令来运行Node-RED,但是在指定red.js
之前,必须手动设定Node进程以及传递给Node-RED本身的相关参数。
以下给出了这两种方式的命令形式:
node-red-pi --max-old-space-size=128 --userDir /home/user/node-red-data/ node --max-old-space-size=128 red.js --userDir /home/user/node-red-data/
开机时启动、停止和监控应用的方法有很多,对于树莓派用户,强烈建议按照这些说明进行操作。
后面的内容对于大多数用户都可以直接利用,但对于Windows用户,可能无法将PM2作为服务自动运行,可能更适合采用之后的NSSM选项。
PM2是Node.js的进程管理工具,利用它可以非常容易地实现开机应用自动启动以及必要时自动启动的功能。
Note: PM2的发行许可为GNU-AGPL-3.0,在部署前请查看许可的相关条款。
sudo npm install -g pm2
注意: sudo
仅适用于Linux或OS X中的非root用户,如果运行在Windows上,那么就需要以系统身份管理员来执行,而无需使用sudo
命令。
另外在Windows上,你还要保证tail.exe
已经在目录中安装好,具体情况请参照此处的说明。
node-red
命令的具体位置。如果是以全局方式安装的Node-RED,那么对于Linux或OS X系统,那么node-red
命令就有可能在/usr/bin/node-red
或/usr/local/bin/node-red
中,我们可以利用which node-red
来确定其确切的位置。
如果是本地安装,那么它就应该是你运行npm install
命令的那个目录中的node_modules/node-red/bin/node-red
。
以下命令可使PM2运行Node_RED,其中假设/usr/bin/node-red
为node-red
命令的存放地址。
另外,--
必须出现在传递给node-red的其他任何参数之前。
pm2 start /usr/bin/node-red -- -v
注意: 如果运行在树莓派或BeagleBone Black这类内存受限设备上,你还必须另外再加入一个参数:
pm2 start /usr/bin/node-red --node-args="--max-old-space-size=128" -- -v
注意: 如果希望以root用户身份运行,就必须利用--userDir
选项,指定保存用户数据的位置。
执行上述指令后,Node-RED将会以后台方式启动运行。你还可以利用下面的指令来查看相关进程信息并访问运行日志:
pm2 info node-red pm2 logs node-red
关于利用PM2管理进行的更多信息请访问这里。
PM2能够自动生成和配置一个与运行平台相适应的启动脚本。
执行以下命令,并按照出现的提示进行操作:
pm2 save pm2 startup
对于更新版的Linux系统,还可以使用systemd
pm2 startup systemd
注意: 最近在Github上提出了一个 open问题,对于Linux用户必须通过手工编辑所生成/etc/init.d/pm2-init.sh
来解决,具体做法是将其中的
export PM2_HOME="/root/.pm2"
替换为正确的目录,比如:
export PM2_HOME="/home/{youruser}/.pm2"
最后,重启系统,并检查所有应用是否按预期方式自动启动。
以下为社区成员所提供的替代方案。
systemd脚本(预装版树莓派专用) by @NodeRED (linux)
systemd脚本 by Belphemur (linux)
init.d脚本 by dceejay (linux)
init.d脚本 by Belphemur (linux)
Launchd脚本 by natcl (OS X)
利用NSSM以Windows服务方式运行 by dceejay
以Windows或OS X服务方式运行 by Ben Hardill
Node-RED本身只包含了一些核心的基本节点,但还有大量来自于Node-RED项目和广大社区的其他节点可以使用。
你可以在Node-RED代码库或npm仓库中寻找所需要的节点。
从0.15版开始,你可以直接通过编辑器安装节点。具体做法是,在右上角的菜单中选择管理节点面板
,然后在出现的面板中选择安装
标签,这样就可以搜索安装新的节点,并启用或禁用已有节点了。
既可以将npm包装的节点安装到保存用户数据的本地目录中(默认为$HOME/.node-red
):
cd $HOME/.node-red npm install
也可以安装到和Node-RED在一起的全局目录中:
sudo npm install -g
但是这样你需要重启Node-RED,以便它能够获取到新的节点。
将.js
和.html
文件安装到保存用户数据目录中的nodes
子目录,也是安装节点的一个可行方式。如果这些节点中存在一些npm依赖项,那么也必须将其安装到用户数据目录中。但建议只是在开发阶段使用这种方式。
注意: 如果你使用的是Raspian Jessie中的预装版本,请参考升级树莓派的相关说明,使用update-nodejs-and-nodered
脚本。
目前,我们建议使用版本为2或3的npm(不建议使用版本4),在升级前,请先运行npm -v
检查一下你所安装的版本,如果必要,请运行
sudo npm i -g [email protected] hash -r
如果你是以全局方式安装的Node-RED,那么可以通过以下指令升级到最新版本:
sudo npm cache clean sudo npm update -g --unsafe-perm node-red
如果要检查安装到用户目录中的节点是否过期,可以执行:
cd ~/.node-red npm outdated
执行后,将会列出所有需要升级节点的列表,如需升级,可执行:
npm update # to update all nodes, or npm update foo # to only update a node called foo
升级后,需要暂停并重启Node-RED。
如果要升级Node.js,比如从v0.10.x升级到v4.6.x,最好先停用Node-RED,然后按照下面的方式重装:
sudo npm cache clean sudo npm install -g --unsafe-perm node-red
可能还需要重新编译那些有二进制依赖项的节点,如果你是按建议将它们安装在~/.node-red
目录中,那么可以这么做:
cd ~/.node-red npm rebuild
安装完成后,需要重启Node-RED。
对于0.10.4之前的版本,默认是将用户数据写入Node-RED的安装目录,这使得升级的过程变得非常痛苦。下面我们将带领你,将既有的数据从安装目录中移出。
首先选择你想用来保存数据的地方,Node-RED 0.10.4的默认存储地址为$HOME/.node-red
,你也可以利用--userDir
改变这项设置。
备份整个Node-RED安装目录,以防万一。
将以下文件从Node-RED安装目录移至你选择的用户数据目录:
settings.js
- 如果你对它进行了修改
所有以flows_
开头的文件
.config.json
.sessions.json
- 如果有这个文件的话
整个lib/
目录
在nodes/
下手工安装的所有附加节点
对于已移动的数据,应确保执行Node-RED的用户对新目录和文件具有相应读写权限。
删除原有Node-RED安装目录,依照安装说明安装新版本系统。
如果已经用npm安装了附加节点,或手工复制了其npm依赖项,那么需要重新安装它们。
注意: 之所以要在安装时使用--unsafe-perm
选项,是因为当node-gyp尝试重新编译本地代码库时,会以”nobody”身份执行,这就造成在存取某些目录资源时有可能会发生错误,并使得与问题相关的节点无法被正常安装(如serialport)。这一选项可使其在安装期间具有访问特权,确保相关节点在升级过程中能被正确安装。
一旦Node-RED运行起来,那么你就可以利用一个本地浏览器,通过http://localhost:1880来访问它。如果你能获得Node-RED实例的ip地址或名称,还可以利用其它机器上的浏览器,通过http://{Node-RED-machine-ip-address}:1880对其进行访问。
Inject节点允许你以点击节点按钮(手动)或设置时间间隔(自动)的方式,向流程中注入消息。
从节点面板中向工作区中拖入一个Inject节点。
打开边栏(Ctrl加空格键,或者通过下拉菜单),选择信息标签。
选中新加入的Inject节点,仔细查看其相关功能和属性信息。
Debug节点的作用是产生能够显示在调试面板中的消息。默认它只显示消息的载荷部分内容,但也可以通过设定,显示整个消息对象。
通过在一个节点的输出端口和另一个节点的输入端口之间拖拽,将Inject和Debug节点连接起来。
此时的节点还只存在于编辑器中,必须将其部署到服务器上。
要做到这点,只需点击一下部署按钮,就可以了。
在选中边栏上调试标签的情况下,点击Inject按钮,应该可以在边栏中看到出现的数字。默认情况下,Inject节点使用自1970年1月1日以来的毫秒数作为消息载荷。接着,我们再增加一下有用的功能。
Function节点允许你将接受到的消息传递给JavaScript函数。
如果要在Inject和Debug节点之间,连入Function节点,需要先删除已有的连线(选取连线,然后点击键盘上的删除键)。
在Function节点上双击后,将会弹出一个编辑器窗口,将以下代码复制到其中的函数输入区域:
// Create a Date object from the payload var date = new Date(msg.payload); // Change the payload to be a formatted Date string msg.payload = date.toString(); // Return the message so it can be sent on return msg;
点击确定关闭编辑器窗口,然后再点击部署按钮。
此时,当你点击Inject按钮时,出现在边栏中消息的可读性将明显变好。
本例中创建的流程采用以下json形式表示,我们可以把它们粘贴到导入窗口中,这样就可以直接将流程导入到编辑器中。
[{"id":"58ffae9d.a7005","type":"debug","name":"","active":true,"complete":false,"x":640,"y":200,"wires":[]},{"id":"17626462.e89d9c","type":"inject","name":"","topic":"","payload":"","repeat":"","once":false,"x":240,"y":200,"wires":[["2921667d.d6de9a"]]},{"id":"2921667d.d6de9a","type":"function","name":"Format timestamp","func":"// Create a Date object from the payload\nvar date = new Date(msg.payload);\n// Change the payload to be a formatted Date string\nmsg.payload = date.toString();\n// Return the message so it can be sent on\nreturn msg;","outputs":1,"x":440,"y":200,"wires":[["58ffae9d.a7005"]]}]
这个例子要稍微复杂一些,它将带入来自于外部资源的数据,并实现一些有用的本地化功能。
访问外部Web网站
从中抓取一些信息
读取信息并将其转换为有用形式
以两种格式将信息输出,其一为JSON对象,可供进一步的使用,其二为逻辑值,用于开启和关闭事物。
在上一个例子中,我们通过点击Inject按钮来触发整个流程。而对于本例,我们将Inject节点设置为,按固定间隔触发流程。
首先将面板上的Inject节点拖拽到工作区中。
然后双击该节点,在弹出的编辑器窗口中,将重复执行间隔设置为每 5 分钟
。
点击确定关闭窗口。
HttpRequest节点可用于在触发时获取Web页面。
拖入工作区后,将其网址
属性设置为:
http://realtimeweb-prod.nationalgrid.com/SystemData.aspx
还可以为其设置一个容易识别的名称。
加入一个Function节点,并在其中添加以下代码:
// does a simple text extract parse of the http output to provide an
// object containing the uk power demand, frequency and time
if (~msg.payload.indexOf('")[1].split("<")[0]);
msg.payload.frequency = parseFloat(fre.split(">")[1].split("<")[0]);
msg2 = {};
msg2.payload = (msg.payload.frequency >= 50) ? true : false;
return [msg,msg2];
}
return null;
设Function节点的输出端口数为2。
添加两个Debug节点。
把Inject节点的输出端口和HttpRequest节点的输入端口连起来。
把HttpRequest节点的输出端口和Function节点的输入端口连起来。
把Function节点的各输出端口连接到不同Debug节点的输入端口上。
至此,所有节点还都在编辑器里,需要把它们部署到服务器上。
点击部署按钮。
选中调试边栏标签后(Ctrl加空格键,或通过下拉菜单,并点击调试标签),点击Inject按钮,应该可以看到类似下面形式的内容出现:
(Object) { "demand": 34819, "frequency": 50.04 }
而在另一个调试面板中可以看到:
(boolean) true
你现在拥有了一个可以访问互联网信息的流程,能够从中获得英国用电总量的动态数据,并且将其转化为包含demand(单位为兆瓦)和frequency(单位为赫兹)两条属性及数据的JavaScript对象形式
该对象经Function节点的第一个输出端口发出。
频率是一个用于表示总体压力的指标,比如当频率低于50赫兹时,表明整个国家电网有可能处于处于超负荷状态。状态标志信息是通过Function节点的第二个输出端口发出的。如果其载荷值为true,那么就表示电网容量满足要求。
本例所创建的流程将以以下json格式表示。如果把它们粘贴到导入窗口(Ctrl加I键,或通过下拉菜单)中,就可以将流程直接导入到编辑器中。
[{"id":"11b032a3.ee4fcd","type":"inject","name":"Tick","topic":"","payload":"","repeat":"","crontab":"*/5 * * * *","once":false,"x":161,"y":828,"z":"6480e14.f9b7f2","wires":[["a2b3542e.5d4ca8"]]},{"id":"a2b3542e.5d4ca8","type":"http request","name":"UK Power","method":"GET","url":"http://realtimeweb-prod.nationalgrid.com/SystemData.aspx","x":301,"y":828,"z":"6480e14.f9b7f2","wires":[["2631e2da.d9ce1e"]]},{"id":"2631e2da.d9ce1e","type":"function","name":"UK Power Demand","func":"// does a simple text extract parse of the http output to provide an\n// object containing the uk power demand, frequency and time\n\nif (~msg.payload.indexOf('\")[1].split(\"<\")[0]);\n msg.payload.frequency = parseFloat(fre.split(\">\")[1].split(\"<\")[0]);\n \n msg2 = {};\n msg2.payload = (msg.payload.frequency >= 50) ? true : false;\n\n return [msg,msg2];\n}\n\nreturn null;","outputs":"2","valid":true,"x":478,"y":828,"z":"6480e14.f9b7f2","wires":[["8e56f4d3.71a908"],["cd84371b.327bc8"]]},{"id":"8e56f4d3.71a908","type":"debug","name":"","active":true,"complete":false,"x":678,"y":798,"z":"6480e14.f9b7f2","wires":[]},{"id":"cd84371b.327bc8","type":"debug","name":"","active":true,"complete":false,"x":679,"y":869,"z":"6480e14.f9b7f2","wires":[]}]
There are many ways you could choose to run Node-RED under Docker. This guide describe some of the ways you can do it.
It assumes you have some basic familiarity with Docker and the Docker Command Line.
We publish three tagged versions of the container to DockerHub:
latest
- uses official Node.JS v4 base image.
slim
- uses Alpine Linux base image.
rpi
- uses RPi-compatible base image.
Using Alpine Linux reduces the built image size (~100MB vs ~700MB) but removes standard dependencies that are required for native module compilation. If you want to add modules with native dependencies, use the standard image or extend the slim image with the missing packages.
To run the latest
container:
docker run -it -p 1880:1880 --name mynodered nodered/node-red-docker
This command will download the nodered/node-red-docker
container from DockerHub and run an instance of it with the name of mynodered
and with port 1880 exposed. In the terminal window you will see Node-RED start. Once started you can then browse to http://{host-ip}:1880
to access the editor.
Hit Ctrl-p
Ctrl-q
to detach from the container. This leaves it running in the background.
To reattach to the container:
docker attach mynodered
To stop the container:
docker stop mynodered
To start the container:
docker start mynodered
Note: your flows will be stored in the file called flows.json
within the container. This can be customised by setting the FLOWS
environment parameter:
docker run -it -p 1880:1880 -e FLOWS=my_flows.json nodered/node-red-docker
Node.js runtime arguments can be passed to the container using an environment parameter (NODE_OPTIONS
). For example, to fix the heap size used by the Node.js garbage collector you would use the following command:
docker run -it -p 1880:1880 -e NODE_OPTIONS="--max_old_space_size=128" nodered/node-red-docker
The container uses the directory /data
as the user configuration directory. To add additional nodes you can open shell into the container and run the appropriate npm install
commands:
# Open a shell in the container docker exec -it mynodered /bin/bash # Once inside the container, npm install the nodes in /data cd /data npm install node-red-node-smooth exit # Restart the container to load the new nodes docker stop mynodered docker start mynodered
It is possible to mount the /data
path on an external volume:
docker run -it -p 1880:1880 -v ~/node-red-data:/data --name mynodered nodered/node-red-docker
This command mounts the host’s ~/node-red-data
directory as the user configuration directory inside the container.
Adding extra nodes to the container can then be accomplished by running npm install
on the host machine:
cd ~/node-red-data npm install node-red-node-smooth docker stop mynodered docker start mynodered
Note: Modules with a native dependencies will be compiled on the host machine's architecture. These modules will not work inside the Node-RED container unless the architecture matches the container's base image. For native modules, it is recommended to install using a local shell or update the package.json and re-build.
The Dockerfiles for these containers are maintained here, each under its own branch.
To build your own version:
git clone https://github.com/node-red/node-red-docker.git cd node-red-docker # Build it with the desired tag docker build -f/Dockerfile -t mynodered: .
Creating a new Docker image, using the public Node-RED images as the base image, allows you to install extra nodes during the build process.
Create a file called Dockerfile
with the content:
FROM nodered/node-red-docker RUN npm install node-red-node-wordpos
Run the following command to build the image:
docker build -t mynodered:.
That will create a Node-RED image that includes the wordpos
nodes.
Updating the base container image is as simple as
docker pull nodered/node-red-docker docker stop mynodered docker start mynodered
You can link containers “internally” within the Docker runtime by using the --link
option.
For example, if you have a container that provides an MQTT broker container called mybroker
, you can run the Node-RED container with the link
parameter to join the two:
docker run -it -p 1880:1880 --name mynodered --link mybroker:broker nodered/node-red-docker
This will make broker
a known hostname within the Node-RED container that can be used to access the service within a flow, without having to expose it outside of the Docker host.
[{"id":"190c0df7.e6f3f2","type":"mqtt-broker","broker":"broker","port":"1883","clientid":""},{"id":"37963300.c869cc","type":"mqtt in","name":"","topic":"test","broker":"190c0df7.e6f3f2","x":226,"y":244,"z":"f34f9922.0cb068","wires":[["802d92f9.7fd27"]]},{"id":"edad4162.1252c","type":"mqtt out","name":"","topic":"test","qos":"","retain":"","broker":"190c0df7.e6f3f2","x":453,"y":135,"z":"f34f9922.0cb068","wires":[]},{"id":"13d1cf31.ec2e31","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":226,"y":157,"z":"f34f9922.0cb068","wires":[["edad4162.1252c"]]},{"id":"802d92f9.7fd27","type":"debug","name":"","active":true,"console":"false","complete":"false","x":441,"y":261,"z":"f34f9922.0cb068","wires":[]}]
我们还刚刚起步,会有更多的内容补充进来。
设置Node-RED
安全
日志
命令行管理
使用函数节点
嵌入其他应用
如有问题、建议或者仅仅是想打个招呼,那么可以通过以下方式实现:
订阅邮件列表 以及博客
加入我们的Slack
在推特上关注@nodered
可利用以下属性对Node-RED进行配置。
当作为一个独立程序运行时,这些属性可以从settings.js
文件中获得,该文件的存放位置可能为:
通过命令行参数--settings|-s
设置
由命令行参数--userDir|-u
指定的用户目录
默认用户目录: $HOME/.node-red/settings.js
Node-RED安装目录
Node-RED中包含一个默认的settings.js
文件,当用户没有提供配置文件,就会使用这个文件。另外,它也可作为你创建自有配置文件的起点,在这里可以找到它的源码。
而当以嵌入式方式运行时,则须通过调用RED.init()
传入配置参数。这种方式有可能会使其中的某些属性被忽略,但可以通过所嵌入的程序替代实现。
flowFile
存储流程代码的文件。默认值: flows_
userDir
保存用户数据的目录,比如流程、凭证文件以及所有代码库数据等。默认值: $HOME/.node-red
nodesDir
用于寻找已安装附加节点的目录。Node-RED一般会默认搜寻userDir目录下的nodes
子目录。该属性允许指定一个额外的目录,这样就可以将节点安装在Node-RED系统之外了。默认值: $HOME/.node-red/nodes
uiHost
用于侦听网络连接的接口设置。默认值: 0.0.0.0
- 所有IPv4接口。仅适用于独立运行方式.
uiPort
用于提供编辑器服务的端口。默认值: 1880
.仅适用于独立运行方式.
httpAdminRoot
编辑器界面的根网址。如果设置为false
, 则所有管理员服务端点将被禁用,包括API端点和编辑器界面。如果想只禁用编辑器界面,请查看后面的disableEditor
属性,默认值: /
httpAdminAuth
弃用: 请查看adminAuth
。在编辑器界面上启用HTTP基本身份认证:httpAdminAuth: {user:"nol", pass:"5f4dcc3b5aa765d61d8327deb882cf99"} ``pass
属性为实际密码的md5哈希值,以下命令可用于产生该数值:node -e "console.log(require('crypto').createHash('md5').update('YOUR PASSWORD HERE','utf8').digest('hex'))"
仅适用于独立运行方式.
httpNodeRoot
所有提供提供HTTP服务节点的根网址。如果设置为false
,则所有基于节点的HTTP服务端点被禁用。默认值: /
httpNodeAuth
启用HTTP基本身份认证,相关格式参看httpAdminAuth
。
httpRoot
为管理员和节点服务端口设置共同的根网址,它将覆盖由httpAdminRoot
和httpNodeRoot
所设置的值。
https
启用https,需要指定专门的参数对象,请参看其定义.仅适用于独立运行方式.
disableEditor
如果设为true
,将会阻止运行时显示编辑器界面,但管理员应用接口将保持可用。默认值: false
.
httpStatic
用于提供静态Web内容服务的本地目录,其中的内容可通过顶级网址/
访问。当使用该属性时,必须同时使用httpAdminRoot
属性,将编辑器界面指向/
以外的其他路径。仅适用于独立运行方式.
httpStaticAuth
对于静态内容启用HTTP基本身份认证,相关格式参看httpAdminAuth
。
httpNodeCors
enables cross-origin resource sharing for the nodes that provide HTTP endpoints, as defined here
httpNodeMiddleware
an HTTP middleware function that is added to all HTTP In nodes. This allows whatever custom processing, such as authentication, is needed for the nodes. The format of the middleware function is documented here.httpNodeMiddleware: function(req,res,next) { // Perform any processing on the request. // Be sure to call next() if the request should be passed // to the relevant HTTP In node. }
logging
currently only console logging is supported. Various levels of logging can be specified. Options are:
fatal - only those errors which make the application unusable should be recorded
error - record errors which are deemed fatal for a particular request + fatal errors
warn - record problems which are non fatal + errors + fatal errors
info - record information about the general running of the application + warn + error + fatal errors
debug - record information which is more verbose than info + info + warn + error + fatal errors
trace - record very detailed logging + debug + info + warn + error + fatal errors
The default level is info
. For embedded devices with limited flash storage you may wish to set this to fatal
to minimise writes to “disk”.
adminAuth
enables user-level security in the editor and admin API. See security for more information.
paletteCategories
defines the order of categories in the palette. If a node’s category is not in the list, the category will get added to the end of the palette. If not set, the following default order is used:['subflows', 'input', 'output', 'function', 'social', 'storage', 'analysis', 'advanced'],
Note: Until the user creates a subflow the subflow category will be empty and will not be visible in the palette.
The theme of the editor can be changed by using the following settings object. All parts are optional.
editorTheme: { page: { title: "Node-RED", favicon: "/absolute/path/to/theme/icon", css: "/absolute/path/to/custom/css/file" }, header: { title: "Node-RED", image: "/absolute/path/to/header/image", // or null to remove image url: "http://nodered.org" // optional url to make the header text/image a link to this url }, deployButton: { type:"simple", label:"Save", icon: "/absolute/path/to/deploy/button/image" // or null to remove image }, menu: { // Hide unwanted menu items by id. see editor/js/main.js:loadEditor for complete list "menu-item-import-library": false, "menu-item-export-library": false, "menu-item-keyboard-shortcuts": false, "menu-item-help": { label: "Alternative Help Link Text", url: "http://example.com" } }, userMenu: false, // Hide the user-menu even if adminAuth is enabled login: { image: "/absolute/path/to/login/page/big/image" // a 256x256 image } },
ui
The home path for the Node-RED-Dashboard add-on nodes can specified. This is relative to any already defined httpNodeRootui : { path: “mydashboard” },
Any node type can define its own settings to be provided in the file.
functionGlobalContext
Function Nodes - a collection of objects to attach to the global function context. For example,functionGlobalContext: { osModule:require('os') }
can be accessed in a function node as:var myos = global.get('osModule');
Note: Prior to Node-RED v0.13, the documented way to use global context was to access it as a sub-property of context
:
context.global.foo = "bar"; var osModule = context.global.osModule;
This method is still supported, but deprecated in favour of the global.get
/global.set
functions. This is in anticipation of being able to persist the context data in a future release.
debugMaxLength
Debug Nodes - the maximum length, in characters, of any message sent to the debug sidebar tab. Default: 1000
mqttReconnectTime
MQTT Nodes - if the connection is lost, how long to wait, in milliseconds, before attempting to reconnect. Default: 5000
serialReconnectTime
Serial Nodes - how long to wait, in milliseconds, before attempting to reopen a serial port. Default: 5000
socketReconnectTime
TCP Nodes - how long to wait, in milliseconds, before attempting to reconnect. Default: 10000
socketTimeout
TCP Nodes - how long to wait, in milliseconds, before timing out a socket. Default: 120000
默认时,并没有对Node-RED编辑器进行任何保护,也就是说,任何人都可以通过访问其IP地址和端口,使用编辑器功能并改变和部署流程,因此,仅适用于在可信网络中运行的情况。
本章主要讲述如何对Node-RED进行保护,共分两个部分:
编辑器和管理API
HTTP节点和静态内容.
为在编辑器和管理API部分启用用户身份验证功能,请在你的settings.js
文件中加入以下内容:
adminAuth: { type: "credentials", users: [{ username: "admin", password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.", permissions: "*" }] }
users
属性为一个用户对象列表,允许你设定多个用户,并且为其设定不同的权限。
上例设置了一个名为admin
的用户,其密码为password
,在编辑器中具有全部权限,注意密码是经过加密的。
注意: 在以前发布的Node-RED中,可以通过设置httpAdminAuth
启用HTTP基本用户身份验证功能,目前这个选项已被弃用,不应再使用了。
可以利用node-red-admin命令行工具,生成适用的密码加密字串:
node-red-admin hash-pw
这个工具会提示你输入希望使用的密码,然后将生成的字串显示在屏幕上,你将其复制到设置文件中。
另外,你还可以通过在Node-RED安装目录中执行以下命令,实现同样的功能:
node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here
前面给出的设置会禁止所有未登录的用户访问编辑器。
而在某些情况下,可能需要向未登录的用户开放某些访问权限。比如最典型的,只读访问编辑器的权利等。要做到这点,可以在adminAuth
设置项中,针对默认用户加入default
属性:
adminAuth: { type: "credentials", users: [ /* list of users */ ], default: { permissions: "read" } }
对Node-RED 0.14之前的版本,用户只能具有以下两类权限的一项:
*
- 完全访问
read
- 只读访问
从Node-RED 0.14开始,可以对权限做细微调整,并且在以前支持的单字串属性基础上,加入对多权限数组的支持。
管理API中的每种方法都定义了不同级别的访问权限,其权限模型是基于资源设计的。比如,为了获取当前流程的设置,用户需要有flows.read
权限,但如果想修改流程,则需要有flows.write
权限。
默认情况下,访问令牌会在被创建七天后过期,目前我们还不能支持令牌更新和延期功能。
可以通过adminAuth
设置项中的sessionExpiryTime
属性自行设定过期时间,也就是在多长时间内,令牌是有效的,单位为秒。例如,将令牌设为一天内有效:
adminAuth: { sessionExpiryTime: 86400, ... }
管理API文档中讲述了如何通过adminAuth
属性来访问API。
除了在设置文件中对用户信息进行硬编码,也可以通过插入代码的方式验证用户身份,这就使得与其它用户认证方式整合成为可能。
以下实例显示了,如何利用一个外部模块,来提供个性化身份验证功能。
将以下代码保存为
文件
var when = require("when"); module.exports = { type: "credentials", users: function(username) { return when.promise(function(resolve) { // Do whatever work is needed to check username is a valid // user. if (valid) { // Resolve with the user object. It must contain // properties 'username' and 'permissions' var user = { username: "admin", permissions: "*" }; resolve(user); } else { // Resolve with null to indicate this user does not exist resolve(null); } }); }, authenticate: function(username,password) { return when.promise(function(resolve) { // Do whatever work is needed to validate the username/password // combination. if (valid) { // Resolve with the user object. Equivalent to having // called users(username); var user = { username: "admin", permissions: "*" }; resolve(user); } else { // Resolve with null to indicate the username/password pair // were not valid. resolve(null); } }); }, default: function() { return when.promise(function(resolve) { // Resolve with the user object for the default user. // If no default user exists, resolve with null. resolve({anonymous: true, permissions:"read"}); }); } }
在settings.js的adminAuth
属性中加载该模块:
adminAuth: require("./user-authentication");
HTTP In节点对外提供的访问路径可以通过基本身份验证的方式加以保护。
在settings.js
文件的httpNodeAuth
属性中,可以单独设定访问该路径的用户名和密码。
httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
pass
属性所使用的格式与adminAuth
相同,详情见生成密码加密字串。
对于httpStatic
属性中设定的静态内容的安全防护,可以通过httpStaticAuth
属性实现,其格式也基本相同。
注意: 在以前版本的Node-RED中,pass
属性采用了MD5加密方式, 因为它不够安全,所以采用了adminAuth
所使用的加密方式来替代它。但为了保持兼容,MD5仍被支持,只是不建议再使用。
By default, Node-RED uses a logger that writes its output to the console. It also supports the use of custom logger modules to allow the output to be sent elsewhere.
The console logger can be configured under the logging
property in settings.js
.
// Configure the logging output logging: { // Console logging console: { level: "info", metrics: false, audit: false } }
There are 3 properties used to configure the logger’s behaviour:
level
Level of logging to be recorded. Options are:
fatal
- only those errors which make the application unusable should be recorded
error
- record errors which are deemed fatal for a particular request
warn
- record problems which are non fatal
info
- record information about the general running of the application
debug
- record information which is more verbose than info
trace
- record very detailed logging
off
- no log messages at all
Other than off
, each level includes messages at higher levels - for example, warn
level will include error
and fatal
level messages.
metrics
When set to true
, the Node-RED runtime outputs flow execution and memory usage information.
Received and sent events in each node are output into the log. For example, the following logs are output from the flow which has inject and debug nodes.
9 Mar 13:57:53 - [metric] {"level":99,"nodeid":"8bd04b10.813f58","event":"node.inject.receive","msgid":"86c8212c.4ef45","timestamp":1489067873391} 9 Mar 13:57:53 - [metric] {"level":99,"nodeid":"8bd04b10.813f58","event":"node.inject.send","msgid":"86c8212c.4ef45","timestamp":1489067873392} 9 Mar 13:57:53 - [metric] {"level":99,"nodeid":"4146d01.5707f3","event":"node.debug.receive","msgid":"86c8212c.4ef45","timestamp":1489067873393}
Memory usage is logged every 15 seconds.
9 Mar 13:56:24 - [metric] {"level":99,"event":"runtime.memory.rss","value":97517568,"timestamp":1489067784815} 9 Mar 13:56:24 - [metric] {"level":99,"event":"runtime.memory.heapTotal","value":81846272,"timestamp":1489067784817} 9 Mar 13:56:24 - [metric] {"level":99,"event":"runtime.memory.heapUsed","value":59267432,"timestamp":1489067784817}
audit
When set to true
, the Admin HTTP API access events are logged. The event includes additional information such as the end point being accessed, IP address and time stamp.
If adminAuth
is enabled, the events include information about the requesting user.
9 Mar 13:49:42 - [audit] {"event":"library.get.all","type":"flow","level":98,"path":"/library/flows","ip":"127.0.0.1","timestamp":1489067382686} 9 Mar 14:34:22 - [audit] {"event":"flows.set","type":"full","version":"v2","level":98,"user":{"username":"admin","permissions":"write"},"path":"/flows","ip":"127.0.0.1","timestamp":1489070062519}
A custom logging module can also be used. For example, the metrics
output may get sent to a separate system for monitoring the performance of the system.
To use a custom logger, edit settings.js
to add a new block in the logging section.
// Configure the logging output logging: { // Console logging console: { level: "info", metrics: false, audit: false }, // Custom logger myCustomLogger: { level: 'debug', metrics: true, handler: function(settings) { return function(msg) { console.log(msg.timestamp, msg.event); } } } } The `level`, `metrics` and `audit` properties are the same as console logging. The `handler` property defines the custom logging handler. It is a function that is called once at start-up, passing in the logger's configuration. It must return a function that will get called with log messages. Multiple custom loggers can be configured - the only reserved name is `console`. #### Example logger The following example adds a custom logger that sends metrics events to a logstash instance over a TCP connection. It is a very quick and simple example - with no error handling or reconnect logic. ~~~~~js logging: { console: { level: "info", metrics: false, audit: false }, logstash: { level:'off', metrics:true, handler: function(conf) { var net = require('net'); var logHost = '192.168.99.100',logPort = 9563; var conn = new net.Socket(); conn.connect(logPort,logHost) .on('connect',function() { console.log("Logger connected") }) .on('error', function(err) { // Should attempt to reconnect in a real env // This example just exits... process.exit(1); }); // Return the function that will do the actual logging return function(msg) { var message = { '@tags': ['node-red', 'test'], '@fields': msg, '@timestamp': (new Date(msg.timestamp)).toISOString() } try { conn.write(JSON.stringify(message)+"\n"); }catch(err) { console.log(err);} } } } }
通过node-red-admin命令行工具,可以实现对node-red实例进行远程管理的功能。
以全局方式安装node-red-admin
,可以在任意路径中调用工具指令:
npm install -g node-red-admin
注意: sudo
仅针对Linux/OS X中的非root用户,如果运行系统为Windows,则需要以系统管理员身份执行命令行指令,而无需使用sudo
命令。
首先,必须将工具指向欲访问的Node-RED实例,默认为http://localhost:1880
,可通过target
命令改变该默认值:
node-red-admin target http://node-red.example.com/admin
如果启启用了用户身份验证功能,那么还必须执行login
:
node-red-admin login
这些指令会创建一个名为~/.node-red/cli-config.json
的文件,其中保存了访问目标和令牌的相关信息。
该工具提供了以下指令:
list
- 列出所有已安装节点
info
- 显示模块或节点信息
enable
- 启用指定模块或节点
disable
- 禁用指定模块或节点
search
- 搜索NPM中Node-RED模块
install
- 从NPM中安装模块
remove
- 移除NPM模块
hash-pw
- 创建adminAuth
和httpNodeAuth
中使用的密码加密字串
函数节点可以让我们使用JavaScript对传入的消息进行处理,然后返回多条消息,以使流程继续执行。
传入的消息一般以对象形式表示,其名称为msg
,通常都会包含一个msg.payload
属性,用来保存消息的主体内容。
其它类型的节点可能会在消息中附加其他专有属性,并且会在文档中加以详细说明。
编写函数
多输出端口
多条消息
异步消息
记录事件
处理错误
存储环境数据
流程环境
全局环境
增加状态
其他模块及函数
输入函数节点的代码实际是JavaScript函数的主体部分,最简单的功能就是直接将收到的消息返回:
return msg;
如果函数返回null
,那么就意味着没有消息传出,流程将被终止。
返回的消息对象不必于传入的对象保持一致,函数可以构建一个完全不同的新返回对象,比如:
var newMsg = { payload: msg.payload.length }; return newMsg;
注意: 构造一个全新的消息对象,有可能会丢失所接收消息的所有属性,并且造成某些流程中断。比如对于使用HTTP In/Response的流程而言,要求msg.req
和msg.res
在端到端的传输过程中一致保留。通常情况下,函数节点应该返回它们所接收到的完整消息对象,只改变其中的某些特性。
函数编辑器允许对输出端口数量进行修改。如果需要多个输出,那么可以通过返回一个消息数组,实现多端口传输功能。
这使得根据特定条件向不同端口发送消息成为可能。比如,以下函数中,将会把主题为banana
的消息发往第二个端口:
if (msg.topic === "banana") { return [ null, msg ]; } else { return [ msg, null ]; }
以下例子则会将原始消息发往第一个端口,而把包含载荷长度的消息发往第二个端口:
var newMsg = { payload: msg.payload.length }; return [msg, newMsg];
函数可以在结果数组中,以消息数组的方式输出多条消息。当多条消息被发往一个输出端口时,后续的节点将按照消息的排列顺序依次进行接收。
下例中的msg1
、msg2
、msg3
将发向第一个端口,msg4
则发往第二个输出端口。
var msg1 = { payload:"first out of output 1" }; var msg2 = { payload:"second out of output 1" }; var msg3 = { payload:"third out of output 1" }; var msg4 = { payload:"only message from output 2" }; return [ [ msg1, msg2, msg3 ], msg4 ];
以下的代码将接收到的载荷分解为词,然后按词逐条发送。
var outputMsgs = []; var words = msg.payload.split(" "); for (var w in words) { outputMsgs.push({payload:words[w]}); } return [ outputMsgs ];
如果函数需要在发出消息前执行一个异步动作,那么就无法在其结束的部分立即返回消息。
解决的办法是,利用node.send()
函数,将传入的消息发送出去。比如:
doSomeAsyncWork(msg, function(result) { node.send({payload:result}); }); return;
如果在函数中使用了异步的回调代码,那么当流程重新部署时,可能需要对一些未处理的请求进行清理,或者,关闭所有的连接,这些都可以通过加入一个close
事件处理器来实现。
node.on('close', function() { // 此处为清理异步事件、关闭连接等的代码 });
如果需要将节点的有关信息以日志方式输出到控制台,那么可以通过以下函数实现:
node.log("Something happened"); node.warn("Something happened you should know about"); node.error("Oh no, something bad happened");
warn
和error
等信息也会被发往流程编辑器中的调试面板。
函数执行过程中,如果遇到有可能造成流程停止的错误时,将不会返回任何结果。为了能够触发同一个标签面板中的Catch节点,函数应该调用node.error
,并且将原始消息作为其第二个参数:
node.error("hit an error", msg);
除msg
对象外,函数还可以将数据保存在context
对象中。
以下实例实现了函数执行次数的保存功能:
// 如果计数器不存在则将其初始化为0 var count = context.get('count')||0; count += 1; // 保存数据 context.set('count',count); // 将其作为输出消息的一部分 msg.count = count;
默认情况下,当Node-RED重启时,环境数据并不能被持久保存。
注意: 在Node-RED v0.13以前版本的文档中,是直接通过context
访问环境数据的:
var count = context.count;
虽然这种方法目前仍被支持,但不赞成继续使用。为保证在今后的版本中,数据持久化相关功能仍然有效,建议使用context.get
/context.set
函数。
在Node-RED 0.13以上版本中,只有context
对象是作用于节点本地范围的,另有一个流程级别的环境对象可以实现同面板所有节点间数据分享,而不是只对Function节点,它是通过flow
对象来访问的:
var count = flow.get('count')||0;
There is also a global context available that is shared by, and accessible to all nodes. For example to make the variable foo available globally across the canvas: 还有一个全局环境对象,可以被所有节点访问。比如下面的变量foo能被全局访问到:
global.set("foo","bar"); // this is now available to other nodes
并且通过.get读取其保存的数值。
var myfoo = global.get("foo"); // this should now be "bar"
也可以在Node-RED启动时,用对象对全局环境进行预填充,这项功能是通过主settings.js文件中的functionGlobalContext项来设置的。
比如,为使所有函数都能访问预置的os
模块:
functionGlobalContext: { osModule:require('os') }
此时,该模块就能以global.get('osModule')
方式被引用了。
如果需要引用外部模块,必须首先利用npm将其手动安装到用户目录中。
cd ~/.node-red npm i name_of_3rd_party_module_to_be_required
注意: 在Node-RED v0.13以前版本文档中,是通过context
的子对象属性来访问全局环境的:
context.global.foo = "bar"; var osModule = context.global.osModule;
虽然该方法仍然适用,但建议用global.get
/global.set
替代它们,因为以这种方式所保存的数据会在未来版本中一直可用。
函数节点也可以像其他节点那样,为自身提供状态装饰功能。如果要设置状态,需调用node.status
函数。例如
node.status({fill:"red",shape:"ring",text:"disconnected"}); node.status({fill:"green",shape:"dot",text:"connected"}); node.status({text:"Just text status"}); node.status({}); // to clear the status
详细参数说明参见节点状态文档
任何状态变化都能被Status节点(需Node-RED v0.12以上版本)所捕获。
Function节点还能使用以下模块及函数:
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来生成数据流,并将其呈现到Web面板上,你希望所有这些功能都出自一个程序。
首先要在应用的package.json
中,像加入其它独立模块那样,加入node-red
依赖项。
以下为在Express应用中嵌入运行时的最小示例。
var http = require('http'); var express = require("express"); var RED = require("node-red"); // Create an Express app var app = express(); // Add a simple route for static content served from 'public' app.use("/",express.static("public")); // Create a server var server = http.createServer(app); // Create the settings object - see default settings.js file for other options var settings = { httpAdminRoot:"/red", httpNodeRoot: "/api", userDir:"/home/nol/.nodered/", functionGlobalContext: { } // enables global context }; // Initialise the runtime with a server and settings RED.init(server,settings); // Serve the editor UI from /red app.use(settings.httpAdminRoot,RED.httpAdmin); // Serve the http nodes UI from /api app.use(settings.httpNodeRoot,RED.httpNode); server.listen(8000); // Start the runtime RED.start();
当使用这种方式时,Node-RED中的settings.js
文件将不再起作用。取而代之的是,像上面的代码那样,将配置信息通过调用RED.init
传入。
更进一步,以下配置项也将被忽略,因为它们都可以通过Express实例配置实现:
uiHost
uiPort
httpAdminAuth
httpNodeAuth
httpStatic
httpStaticAuth
https