将Node-RED以模块的方式嵌入到Nest项目中

693 阅读1分钟

前言

因为最近要搭建物联网平台框架,最后选择Node-RED来做硬件数据采集的解析处理。想要把Node-RED服务放置到现有的Nest项目中启动,经过实践可以如下操作。

环境准备

使用 npm 命令在 Nest 项目的根目录中安装 Node-RED 模块。

npm install node-red -s

可以把Node-RED中的节点模块依赖直接在nest项目中安装,比如我用到的以下这些节点模块

"node-red-contrib-buffer-parser": "^3.2.2",
"node-red-contrib-lvin-crc16": "^1.0.2",
"node-red-contrib-modbus": "^5.26.0",
"node-red-dashboard": "~3.4.0",
"node-red-node-email": "^2.0.0",
"node-red-node-serialport": "^1.0.3",

新建NodeRedModule模块

import { Module, NestModule, MiddlewareConsumer, Logger } from '@nestjs/common';
import { createServer } from 'http';
import express from 'express';
import RED from 'node-red';
import path from 'path';
import settings from 'nodered/settings.js';

@Module({})
export class NodeRedModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    // 用户目录
    settings.userDir = path.join(__dirname, '../../../', 'nodered');

    // 创建一个express应用
    const app = express();

    // 创建一个express服务
    const server = createServer(app);

    // 停止Node-RED实例
    RED.stop();

    // 创建一个Node-RED实例
    RED.init(server, settings);

    // 从httpAdminRoot提供编辑器管理API
    app.use(settings.httpAdminRoot, RED.httpAdmin);

    // 从httpNodeRoot提供节点管理API
    app.use(settings.httpNodeRoot, RED.httpNode);

    // 启动Node-RED实例
    RED.start();

    // 将Node-RED请求路由到适当的处理程序
    consumer.apply(app).forRoutes(settings.httpAdminRoot, settings.httpNodeRoot);

    // 监听页面端口
    setTimeout(() => {
      const uiPort = settings.uiPort;
      server.listen(uiPort, () => {
        new Logger('WsIOT-Service').log(`Node-RED服务已经启动, http://localhost:${uiPort}`);
      });
    }, 100);
  }
}

其中userDir配置项是Node-RED的用户目录,可以根据自己Nest的项目结构进行配置,我这边是在项目根目录中放置了nodered文件夹,如下图所示

nodered文件夹

然后在项目的app.module.ts中导入该NodeRedModule模块启用即可。

在NodeRedModule模块中也可以根据env环境变量进行判断是否启用Node-RED服务