使用多个MQTT节点红色节点的行为不符合预期

时间:2018-03-14 06:49:19

标签: node.js nodes node-red

我有多个MQTT节点,其中配置了不同的主题。现在我将处理多个主题的价值并找出一些假设(基本上是流分析)。

我的期望:

我知道java脚本是单线程的。所以我认为,当收到一个主题数据时,它将被处理,然后只有在完成后才会收到其他主题,等等。

现实:

它像多线程一样工作。

测试案例

流程: MQTT --->处理第二个--->输出

睡眠功能代码(不是真的像处理一样睡觉):

var start = new Date().getTime();
for (var i = 0; i < 1e7; i++)
{
    if ((new Date().getTime() - start) > 1000)
    {
      break;
    }
}
return msg;

现在我将使用for循环连续发布1到100的数据。

我的期望:

现在1,2,3 ...... 100将一个接一个地显示1秒的间隙。所以现在它应该花费大约100秒来显示1到100的值。

现实:

首先它将睡眠100秒然后形成1到100全部将立即显示。 那么这里发生了什么?

流json:

[{"id":"e9a53835.09af38","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"5ffb1b40.1405b4","type":"debug","z":"e9a53835.09af38","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":438,"y":216,"wires":[]},{"id":"a8406277.a78ee","type":"mqtt in","z":"e9a53835.09af38","name":"Test MQTT Queue","topic":"1","qos":"2","broker":"b4c58fab.26844","x":146,"y":120,"wires":[["629e90bb.996ad"]]},{"id":"629e90bb.996ad","type":"function","z":"e9a53835.09af38","name":"Sleep 1 seconds","func":"var start = new Date().getTime();\nfor (var i = 0; i < 1e7; i++)\n{\n    if ((new Date().getTime() - start) > 1000)\n    {\n      break;\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"x":298,"y":168,"wires":[["5ffb1b40.1405b4"]]},{"id":"b4c58fab.26844","type":"mqtt-broker","z":"","name":"","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"2","willRetain":"false","willPayload":"","birthTopic":"","birthQos":"2","birthRetain":"false","birthPayload":""}]

C#发布商功能:

// Retain: false, QOS= 2 on both publisher and client.
for (int i = 1; i <= 10; i++)
{
    client.Publish(1, Encoding.UTF8.GetBytes(i.ToString()), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);
}

1 个答案:

答案 0 :(得分:2)

  1. 第一条消息到达并传递给Function节点,然后执行busy-wait循环,不允许node.js事件循环处理任何其他工作。
  2. 在此期间,剩余的99条消息到达基础MQTT客户端,内部事件排队等待处理它们
  3. 然后第一条消息最终进入Debug节点。 Debug节点异步地将消息传递给websocket - 这意味着该工作被包装在一个事件中并放在node.js事件队列的末尾 - 在99条消息后面。
  4. 然后在接下来的99个事件中发生同样的事情 - 它们被同步处理而没有机会让node.js事件循环取得进展,每个事件都向队列末尾添加了另一个事件以将消息传递给Debug < / LI>
  5. 处理最后一条消息,然后node.js事件循环到达事件以通过websocket处理调试消息,并且所有100条消息都出现在Debug侧栏中
  6. 这里的关键是在node.js世界中同步阻塞是一件坏事。如果要延迟消息,请使用延迟节点,使用计时器这样做 - 从而允许node.js继续在后台处理其他工作。