我有一个MQTT Input节点,可启动PostgreSQL数据库的数据库操作(SELECT和INSERT)。由于数据库操作是通过node-contrib-postgres-multi完成的,由于这些操作被功能节点分隔开了,所以我将消息的一部分保存在flow.set中,稍后再使用flow.get检索。例如,


函数节点保存为flow.set并生成SELECT查询。
连接到PostgreSQL节点。
解析输出,使用flow.get并生成INSERT语句。 />连线到PostgreSQL节点。

我不禁幻想flow.setflow.get不同步。

目前,我正在模拟大约20个设备,以便每秒发布数据,而每次发布的时间戳都增加1秒。绝对没有理由要复制生成的消息。但是,数据库插入节点由于节点索引错误(.pm2/logs/red-out-0.log)中看到的唯一索引冲突而失败。

如果功能节点和数据库处理需要2秒钟,并且MQTT消息(QoS = 0)每秒收到一次,MQTT或Node-RED是否会对其进行缓冲?因此,每个接收到的消息都被视为工作单元,直到它错误地将流错误“泄漏”或“释放”到数据库,HTTP请求,MQTT发布等为止。

评论

您是否使用相同的键将值存储在流上下文中?

@hardillb,是的。

#1 楼

值得记住的是,NodeJS世界中的所有事物都是异步的,这意味着没有任何东西会阻塞事件循环。在这种情况下,这听起来像是您获得了第一条传入消息,并使用固定键将其存储在流中上下文,然后转到“选择”查询。此时,SQL节点将结束做一些网络IO,该IO将在等待数据库响应时阻塞,因此在等待时将放弃执行上下文。

等待新的MQTT消息到达时,它将被立即处理并传递到第一个函数节点,该节点将覆盖流上下文中存储的内容,因为键是相同的。
语句返回的第一条消息将移至第二个功能节点,并且当它从流上下文中检索值时,它将是第二条消息而不是第一条消息。

解决此问题的方法是不使用上下文以保持状态,但要将要保留的信息从msg.payload移至msg对象上的其他键。表现良好的Node-RED节点应始终传递原始msg对象,并且默认情况下仅真正更改msg.payload(有例外,但它们倾向于记录其更改内容和原因)。保持工作单元的状态可以保证只能随着消息在流中的传播而逐步更改。

评论


嗯...我认为Node Red中的流程抽象了同步。将尝试味精。选项。

– cogitoergosum
18年6月24日在13:46

味精。对象存储工作!

– cogitoergosum
18年6月26日在14:14

在您的第三个响应中,当出现新的MQTT消息时,将出现一个新的消息。为该特定的MQTT消息创建对象,对不对?

– cogitoergosum
18年7月25日在9:11

是的,每个新的传入MQTT消息都会获得自己的新消息

– hardillb
18年7月25日在9:23

假设期望一条消息遍历已部署流中的某些节点集。假设还希望下一条消息遍历相同的节点集。那么,一个节点是否可能“看到”与输入端接收到的消息不同的消息?

– cogitoergosum
18年7月25日在11:41