NodeMCU 和 ESP8266:缓慢的 mqtt 发布
NodeMCU and ESP8266: slow mqtt publish
我将 esp8266 与 Marcel 的 NodeMCU 自定义构建生成的固件一起使用 http://frightanic.com/nodemcu-custom-build/
我测试了 "dev" 分支和 "master".
我稍微更改了此处找到的“连接到 MQTT Broker”代码 https://github.com/nodemcu/nodemcu-firmware
-- init mqtt client with keepalive timer 120sec
m = mqtt.Client("clientid", 120, "user", "password")
m:on("connect", function(con) print ("connected") end)
m:on("offline", function(con) print ("offline") end)
-- m:connect( host, port, secure, auto_reconnect, function(client) )
-- for secure: m:connect("192.168.11.118", 1880, 1, 0)
-- for auto-reconnect: m:connect("192.168.11.118", 1880, 0, 1)
m:connect("192.168.11.118", 1880, 0, 0, function(conn) print("connected") end)
-- publish a message with data = hello, QoS = 0, retain = 0
local i = 1
while i < 10 do
m:publish("/topic","hello",0,0, function(conn) print("sent") end)
i = i + 1
end
m:close();
我正在使用 mosquitto 作为 mqtt 代理,我已经启动了所有主题的订阅者 #。
结果是:消息正确到达,但到达订阅者的速度真的很慢(每条大约 1 秒)...为什么?
我也尝试更改 mqtt 架构以支持 UDP..esp8266 快速发送 100 条消息。
更新 1#:
我又做了一些实验:
- 测试经纪人和
具有 [android phone + mqtt 发布者] 的订阅者,订阅者
立即接收消息
- 我加载了一个启用了 "debug" 的 nodemcu
我有一个有趣的发现:继续阅读
根据我的理解阅读调试日志和源代码..
有一种队列将消息保存在内存中,计时器(我不知道 frequency/interval)从队列中读取消息并通过 mqtt 发送。
如果尝试发送 100 条消息,队列会增加,但无法同时发送消息(可能存在竞争条件?)。
这里还有第二个问题,在排队超过 15 条消息后,固件崩溃并且设备重新启动:这似乎是内存不再可用的症状。
这可能不是您正在寻找的答案,但是是的,NodeMCU MQTT 使用内部消息队列。它是 2015 年 3 月末 added。由于 NodeMCU API 的异步特性,添加了它。
如果您连续两次调用 m.publish
,请记住它们是异步的,在触发第二条消息之前没有足够的时间传送第一条消息。在引入该队列之前,如果您循环发布,固件只会崩溃。
我进一步简化了您的代码并添加了一些调试语句:
m = mqtt.Client("clientid", 120, "user", "password")
m:connect("m20.cloudmqtt.com", port, 0, function(conn)
print("MQTT connected")
for i=1,10 do
print("MQTT publishing...")
m:publish("/topic", "hello", 0, 0, function(conn)
print("MQTT message sent")
print(" heap is " .. node.heap() .. " bytes")
end)
print(" heap is " .. node.heap() .. " bytes in loop " .. i)
end
end)
知道对 m.publish
的调用是异步的,输出应该不会太令人惊讶:
MQTT connected
MQTT publishing...
heap is 37784 bytes in loop 1
MQTT publishing...
heap is 37640 bytes in loop 2
MQTT publishing...
heap is 37520 bytes in loop 3
MQTT publishing...
heap is 37448 bytes in loop 4
MQTT publishing...
heap is 37344 bytes in loop 5
MQTT publishing...
heap is 37264 bytes in loop 6
MQTT publishing...
heap is 37192 bytes in loop 7
MQTT publishing...
heap is 37120 bytes in loop 8
MQTT publishing...
heap is 37048 bytes in loop 9
MQTT publishing...
heap is 36976 bytes in loop 10
sent
heap is 38704 bytes
sent
heap is 38792 bytes
sent
heap is 38856 bytes
sent
heap is 38928 bytes
sent
heap is 39032 bytes
sent
heap is 39112 bytes
sent
heap is 39184 bytes
sent
heap is 39256 bytes
sent
heap is 39328 bytes
sent
heap is 39400 bytes
您看到可用堆 space 在发布时减少,并在队列清空时再次增加。
我将 esp8266 与 Marcel 的 NodeMCU 自定义构建生成的固件一起使用 http://frightanic.com/nodemcu-custom-build/ 我测试了 "dev" 分支和 "master".
我稍微更改了此处找到的“连接到 MQTT Broker”代码 https://github.com/nodemcu/nodemcu-firmware
-- init mqtt client with keepalive timer 120sec
m = mqtt.Client("clientid", 120, "user", "password")
m:on("connect", function(con) print ("connected") end)
m:on("offline", function(con) print ("offline") end)
-- m:connect( host, port, secure, auto_reconnect, function(client) )
-- for secure: m:connect("192.168.11.118", 1880, 1, 0)
-- for auto-reconnect: m:connect("192.168.11.118", 1880, 0, 1)
m:connect("192.168.11.118", 1880, 0, 0, function(conn) print("connected") end)
-- publish a message with data = hello, QoS = 0, retain = 0
local i = 1
while i < 10 do
m:publish("/topic","hello",0,0, function(conn) print("sent") end)
i = i + 1
end
m:close();
我正在使用 mosquitto 作为 mqtt 代理,我已经启动了所有主题的订阅者 #。
结果是:消息正确到达,但到达订阅者的速度真的很慢(每条大约 1 秒)...为什么?
我也尝试更改 mqtt 架构以支持 UDP..esp8266 快速发送 100 条消息。
更新 1#:
我又做了一些实验:
- 测试经纪人和 具有 [android phone + mqtt 发布者] 的订阅者,订阅者 立即接收消息
- 我加载了一个启用了 "debug" 的 nodemcu 我有一个有趣的发现:继续阅读
根据我的理解阅读调试日志和源代码.. 有一种队列将消息保存在内存中,计时器(我不知道 frequency/interval)从队列中读取消息并通过 mqtt 发送。 如果尝试发送 100 条消息,队列会增加,但无法同时发送消息(可能存在竞争条件?)。
这里还有第二个问题,在排队超过 15 条消息后,固件崩溃并且设备重新启动:这似乎是内存不再可用的症状。
这可能不是您正在寻找的答案,但是是的,NodeMCU MQTT 使用内部消息队列。它是 2015 年 3 月末 added。由于 NodeMCU API 的异步特性,添加了它。
如果您连续两次调用 m.publish
,请记住它们是异步的,在触发第二条消息之前没有足够的时间传送第一条消息。在引入该队列之前,如果您循环发布,固件只会崩溃。
我进一步简化了您的代码并添加了一些调试语句:
m = mqtt.Client("clientid", 120, "user", "password")
m:connect("m20.cloudmqtt.com", port, 0, function(conn)
print("MQTT connected")
for i=1,10 do
print("MQTT publishing...")
m:publish("/topic", "hello", 0, 0, function(conn)
print("MQTT message sent")
print(" heap is " .. node.heap() .. " bytes")
end)
print(" heap is " .. node.heap() .. " bytes in loop " .. i)
end
end)
知道对 m.publish
的调用是异步的,输出应该不会太令人惊讶:
MQTT connected
MQTT publishing...
heap is 37784 bytes in loop 1
MQTT publishing...
heap is 37640 bytes in loop 2
MQTT publishing...
heap is 37520 bytes in loop 3
MQTT publishing...
heap is 37448 bytes in loop 4
MQTT publishing...
heap is 37344 bytes in loop 5
MQTT publishing...
heap is 37264 bytes in loop 6
MQTT publishing...
heap is 37192 bytes in loop 7
MQTT publishing...
heap is 37120 bytes in loop 8
MQTT publishing...
heap is 37048 bytes in loop 9
MQTT publishing...
heap is 36976 bytes in loop 10
sent
heap is 38704 bytes
sent
heap is 38792 bytes
sent
heap is 38856 bytes
sent
heap is 38928 bytes
sent
heap is 39032 bytes
sent
heap is 39112 bytes
sent
heap is 39184 bytes
sent
heap is 39256 bytes
sent
heap is 39328 bytes
sent
heap is 39400 bytes
您看到可用堆 space 在发布时减少,并在队列清空时再次增加。