我试图通过从我的笔记本电脑发送POST来使用ESP8266-01切换LED(使用node.js)
我现在有一个内存问题,因为每当我发送POST请求时,ESP中使用的内存会增加,堆内存会减少,并且当没有内存时它会崩溃(重启)。
有什么想法吗?
这是我在ESP方面的代码(main.lua):
gpio.mode(3, gpio.OUTPUT)
srv=net.createServer(net.TCP,28800)
print("Server created... \n")
local pinState=0
srv:listen(80,function(conn)
conn:on("receive", function(conn,request)
local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
if(method == nil)then
_, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
end
local message={}
print("Method:"..method);
if(method == "POST")then
if(pinState==0)then
gpio.write(3,gpio.HIGH)
pinState=1
print("LED ON")
message[#message + 1] = "HTTP/1.1 200 OK\r\n"
message[#message + 1] = "Content-Type: text/html\r\n\r\n"
message[#message + 1] = "POST request successfully received\r\n"
elseif(pinState==1)then
gpio.write(3,gpio.LOW)
pinState=0
print("LED OFF")
message[#message + 1] = "HTTP/1.1 200 OK\r\n"
message[#message + 1] = "Content-Type: text/html\r\n\r\n"
message[#message + 1] = "POST request successfully received\r\n"
end
elseif(method == "GET")then
message[#message + 1] = "HTTP/1.1 200 OK\r\n"
message[#message + 1] = "Content-Type: text/html\r\n\r\n"
message[#message + 1] = "LED STATE="..tostring(pinState).."\r\n"
end
local function send()
if #message > 0 then
conn:send(table.remove(message, 1))
else
conn:close()
end
end
conn:on("sent", send)
send()
local message={}
local _, _, method, path, vars= {}
local heapSize=node.heap()
if heapSize<1000 then
node.restart()
end
collectgarbage()
print("Memory Used:"..collectgarbage("count"))
print("Heap Available:"..heapSize)
end)
end)
在node.js上:
var request = require('request');
// Configure request
var options = {
url: 'http://192.168.1.91',//ESP's IP address
method: 'POST'
}
// Start the request
request(options, function (error, response, body)
{
if(!error)
{
return console.log('Server responded with:',body);
}
if(error)
{
return console.error('ERROR:', error);
}
})
我的init.lua只是连接到Wifi。
感谢您的帮助!
雷伊
答案 0 :(得分:2)
您似乎根据自己的实施情况NodeMCU docs with the socket:send
example出现了问题。我们讨论了它并修复了它。
您的代码的改进版本是:
gpio.mode(3, gpio.OUTPUT)
srv = net.createServer(net.TCP, 28800)
print("Server created... \n")
local pinState = 0
srv:listen(80, function(conn)
conn:on("receive", function(sck, request)
local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
if (method == nil) then
_, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
end
local message = {}
message[#message + 1] = "HTTP/1.1 200 OK\r\n"
message[#message + 1] = "Content-Type: text/html\r\n\r\n"
print("Method:" .. method);
if (method == "POST") then
message[#message + 1] = "POST request successfully received\r\n"
if (pinState == 0) then
gpio.write(3, gpio.HIGH)
pinState = 1
print("LED ON")
elseif (pinState == 1) then
gpio.write(3, gpio.LOW)
pinState = 0
print("LED OFF")
end
elseif (method == "GET") then
message[#message + 1] = "LED STATE=" .. tostring(pinState) .. "\r\n"
end
local function send(sk)
if #message > 0 then
sk:send(table.remove(message, 1))
else
sk:close()
message = nil
print("Heap Available:" .. node.heap())
end
end
sck:on("sent", send)
send(sck)
end)
end)
我删除了填充message
的一些重复代码,我还删除了“重置”和GC代码(不再相关)。但真正的问题是在回调函数中关闭了upvalues。
每个回调函数都应该使用自己传递的套接字实例的副本,而不是引用包装回调函数。
srv:listen(80, function(conn)
,回调中的套接字变量为conn
。sck
。它应该在该函数中被引用为sck
(sck:on()
和send(sck)
)。socket:on("sent")
回调本身接收/ socket实例。您原来的send()
函数并没有使用它,而是使用了conn
。因此,我添加了sk
并在send()
内完全使用此内容。答案 1 :(得分:0)
您的on sent sent call应该接受一个参数,一个连接。你应该设置与发送处理程序处于同一级别的接收 - 在接收时传递给的conn不一定是传递给srv:listen的conn。
最后,字符串文字的冗余副本是浪费内存,(尽管这可能不会导致它泄漏。)
答案 2 :(得分:0)
所以Marcel的解决方案有效。
这是解决问题的另一种选择:
var str='<d:BC_1MONTH m:type="Edm.Double">0.11</d:BC_1MONTH>';
str= str.split(" ");
str= str[0].split(":");
console.log(str[1]);