Node-RED 使用实例,拖拉拽生成对外服务

Node-RED 是一种编程工具,用于以新颖有趣的方式将硬件设备、API 和在线服务连接在一起。

它提供了一个基于浏览器的编辑器,可以使用调色板中的各种节点轻松地将流连接在一起,只需单击一下即可部署到其运行时。

——这是官网的说法,不过即使你的工作和物联网、硬件设备毫不相关,也可以从流程编排中受益。

你可以仅使用 Node-RED 连接各种各样的数据源,并将其转换为对外开放的在线服务。

下面将介绍几个应用实例。

获取 bingimg 网站图片列表,并生成对外 API

bingimg 是一个必应壁纸采集站,网站本身没有提供对外服务的 API。

Node-RED 使用实例,拖拉拽生成对外服务

[
{
"id": "d75decd7ba414ab0",
"type": "tab",
"label": "爬取bingimg网站图片列表",
"disabled": false,
"info": "",
"env": []
},
{
"id": "3d950cd634058fc9",
"type": "http in",
"z": "d75decd7ba414ab0",
"name": "",
"url": "/api/bingimg",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 100,
"y": 80,
"wires": [
[
"5b8537791d63163c"
]
]
},
{
"id": "1c53ec3ffa6ae53d",
"type": "function",
"z": "d75decd7ba414ab0",
"name": "解析并转换消息",
"func": "const $ = cheerio.load(msg.payload);\n\nconst getPagination = () => {\n    const pagination = $('ul.pagination')\n    const curPage = parseInt(pagination.find('li.active a').text())\n    const totalPage = parseInt(pagination.find('li').eq(pagination.find('li').length - 4).text())\n\n    return {\n        curPage, totalPage\n    }\n}\n\nconst getThumbnail = (item) => {\n    const node = $(item)\n    const imgs = node.find('.card_date_div a')\n\n    return {\n        title: node.find('.card_title').text().trim(),\n        subTitle: node.find('.card_subtitle').text().trim(),\n        publishDate: node.find('.card_date_div .card_foot').eq(0).text(),\n        url: {\n            HD: imgs.eq(0).attr()?.href,\n            UHD: imgs.eq(1).attr()?.href\n        }\n    }\n}\n\nconst data = Array.from($('.thumbnail')).map(getThumbnail)\nconst { curPage, pageSize, totalPage } = getPagination()\n\nmsg.payload = {\n    data,\n    curPage,\n    pageSize,\n    totalPage\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [
{
"var": "cheerio",
"module": "cheerio"
}
],
"x": 420,
"y": 80,
"wires": [
[
"29f1f02a71644ca5"
]
]
},
{
"id": "6344f3ed693ad033",
"type": "http request",
"z": "d75decd7ba414ab0",
"name": "调用 bingimg 服务",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://www.bingimg.cn/list{{{id}}}",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 350,
"y": 180,
"wires": [
[
"1c53ec3ffa6ae53d",
"7c945d9983f3957f"
]
]
},
{
"id": "29f1f02a71644ca5",
"type": "http response",
"z": "d75decd7ba414ab0",
"name": "",
"statusCode": "200",
"headers": {},
"x": 600,
"y": 80,
"wires": []
},
{
"id": "5b8537791d63163c",
"type": "change",
"z": "d75decd7ba414ab0",
"name": "设置请求参数",
"rules": [
{
"t": "move",
"p": "req.query.curPage",
"pt": "msg",
"to": "id",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 140,
"y": 180,
"wires": [
[
"6344f3ed693ad033"
]
]
},
{
"id": "7c945d9983f3957f",
"type": "debug",
"z": "d75decd7ba414ab0",
"name": "debug 1",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 540,
"y": 260,
"wires": []
}
]

使用上面的编排流程,就生成了一个 API,这个 API 的调用详情如下:

Node-RED 使用实例,拖拉拽生成对外服务

在这个过程中,我们使用了五个节点来完成了这件事:
首先是 http in 节点,配置了 API 的请求方式和 URL。

Node-RED 使用实例,拖拉拽生成对外服务

这样可以使用 GET 请求访问 /api/bingimg 来获取数据。

之后使用 change 节点获取到调用接口传入的 curPage 参数。参数在 msg.query 下面,转换成 msg.id,给后续节点使用

Node-RED 使用实例,拖拉拽生成对外服务

配合后续 http request 节点,使用插值的方式获取上一步传入的 msg.id

Node-RED 使用实例,拖拉拽生成对外服务
这一步请求 bingimg 的网页,将响应内容原样传递到下一个节点处理

Node-RED 使用实例,拖拉拽生成对外服务
下一步是 function 节点,用来处理上一步请求 bingimg 返回的网页数据。

返回的网页是 html,我们使用 cheerio 来解析网页,提取需要的信息。

得益于 Node-RED 基于 Node.js 平台,npm 上面支持 Node.js 的包都可以使用。

在 function 节点中,可以在 Setup 下面指定外部的 node 包,只需要如图配置 cheerio,就可以在函数中用类似 jQuery 的方式提取数据。

Node-RED 使用实例,拖拉拽生成对外服务

在 Setup 中指定的包,可以直接使用,无需 require

Node-RED 使用实例,拖拉拽生成对外服务
处理之后的值放到 msg.payload 中,直接交给最后的 response 节点

Node-RED 使用实例,拖拉拽生成对外服务
在 response 节点中设置响应状态码即可。
跨域等响应也可以在这里配置。

定时推送消息

这里实现了一个简易的 websocket 推送消息接口。每 5s 调用一次 hitokoto 接口,获取消息后推送到 websocket 通道,订阅用户就可即时收到消息。

Node-RED 使用实例,拖拉拽生成对外服务

[
{
"id": "187ddef186859e69",
"type": "tab",
"label": "定时推送消息",
"disabled": false,
"info": "",
"env": []
},
{
"id": "16581924dcbb397b",
"type": "inject",
"z": "187ddef186859e69",
"name": "触发定时任务",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "5",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 120,
"y": 40,
"wires": [
[
"e03649ad2bb10481"
]
]
},
{
"id": "96acd12dd0d087c4",
"type": "websocket out",
"z": "187ddef186859e69",
"name": "推送消息",
"server": "0adc9c4d5e53170b",
"client": "",
"x": 600,
"y": 60,
"wires": []
},
{
"id": "e03649ad2bb10481",
"type": "http request",
"z": "187ddef186859e69",
"name": "",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://v1.hitokoto.cn/?c=a",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 220,
"y": 120,
"wires": [
[
"3a8f6b0d08c5b777"
]
]
},
{
"id": "3a8f6b0d08c5b777",
"type": "function",
"z": "187ddef186859e69",
"name": "转换成一句话",
"func": "const message = msg.payload.hitokoto.trim()\nconst source = msg.payload.from.trim()\n\nmsg.payload = `${message} ——${source}`\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 440,
"y": 140,
"wires": [
[
"96acd12dd0d087c4"
]
]
},
{
"id": "0adc9c4d5e53170b",
"type": "websocket-listener",
"path": "/ws/greeting",
"wholemsg": "false"
}
]

流程如上,使用了 inject、request、function、websocket out 节点完成了这个任务。

Node-RED 使用实例,拖拉拽生成对外服务

inject 节点用来手动或定期将消息注入流中。在这里配置了每隔 5s 周期性执行任务。

后面连接 request 节点调用 hitokoto 服务

Node-RED 使用实例,拖拉拽生成对外服务
调用服务返回的内容在 function 中处理成一句话

Node-RED 使用实例,拖拉拽生成对外服务

最后使用 websocket out 节点配置输出

Node-RED 使用实例,拖拉拽生成对外服务

配置完成后,可以创建 websocket 订阅。下面是最终效果,通过使用 在线调试工具 呈现

Node-RED 使用实例,拖拉拽生成对外服务

还有更多

上面展示了 Rest API 服务和定时推送两种方式。除了这两种情况外,借助流程编排和内置节点,还可以用作BFF、接口自动化测试等场景。配合其他服务,甚至可以实现每天给女朋友发早安晚安等功能(笑)。

在开发上面示例的过程中,第三方接口的返回结果,我如何能看到?这就涉及到了调试。

如何调试节点?

在预设节点列表中,有一个 debug 节点,可以连接到任意一个想要观察的节点后面

Node-RED 使用实例,拖拉拽生成对外服务

debug 节点可以指定将信息输出到调试窗口、控制台等地

Node-RED 使用实例,拖拉拽生成对外服务

配置为调试窗口后,一旦执行到这个节点,就会展示在右侧

Node-RED 使用实例,拖拉拽生成对外服务

原文链接:https://juejin.cn/post/7247306840198594615 作者:一线轨迹

(0)
上一篇 2023年6月23日 上午10:57
下一篇 2023年6月23日 上午11:08

相关推荐

发表回复

登录后才能评论