Lua 具有自动更新功能的NodeMCU超小型web服务器内存不足

Lua 具有自动更新功能的NodeMCU超小型web服务器内存不足,lua,nodemcu,Lua,Nodemcu,我正在测试一个具有自动更新功能的小型Lua web服务器。HTML代码每秒都会重定向到web服务器本身。因此,客户端的web浏览器总是从服务器获取新数据,而不是从服务器获取新数据 使用浏览器的缓存 如果我在一段时间后仅与一个客户端(我的PC或智能手机)连接,NodeMCU板会崩溃,并显示以下消息: 恐慌:调用LuaAPI时发生未受保护的错误(因此WebSrv测试。Lua:27:内存不足) 我使用了Marcel Stoer的代码,他回答了类似的“内存不足” 我修改了Marcel的Lua代码,但随着

我正在测试一个具有自动更新功能的小型Lua web服务器。HTML代码每秒都会重定向到web服务器本身。因此,客户端的web浏览器总是从服务器获取新数据,而不是从服务器获取新数据 使用浏览器的缓存

如果我在一段时间后仅与一个客户端(我的PC或智能手机)连接,NodeMCU板会崩溃,并显示以下消息:

恐慌:调用LuaAPI时发生未受保护的错误(因此WebSrv测试。Lua:27:内存不足)

我使用了Marcel Stoer的代码,他回答了类似的“内存不足”

我修改了Marcel的Lua代码,但随着时间的推移,该代码仍然会占用所有堆内存

我把问题缩小了一点:如果HTML代码的刷新频率低于30秒,代码就会占用堆内存

那么,我必须如何修改这段代码以实现恒定的堆内存使用率呢

致以最良好的祝愿

斯特凡

tmr.alarm(0, 1000, 1, function()
   if wifi.sta.getip() == nil then
      print("trying to connect to AccessPoint...")
   else
      own_ip, netmask, gateway=wifi.sta.getip()
      print("connected to AccessPoint:")
      print("IP Info: \nIP Address of this device: ",own_ip)
      print("Netmask: ",netmask)
      print("Gateway Addr: ",gateway,"\n")
      print("type IP-Address "..own_ip.." into your browser to display SHT-31-website")
      tmr.stop(0)
   end
end)

counter = 0
srv = net.createServer(net.TCP, 28800)
print("Server created... \n")

srv:listen(80, function(conn)
    conn:on("receive", function(sck, request)
        local message = {}
        counter = counter + 1
        message[#message + 1] = "<head> <meta http-equiv=refresh content=1; URL=http://"..own_ip.."> </head>"
        message[#message + 1] = "<h1> ESP8266 SHT-31 Web Server Ver 003</h1>"
        message[#message + 1] = "<h2>some more text blabla blub"..counter.."</h2>"
        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)
tmr.报警(0、1000、1、函数()
如果wifi.sta.getip()==nil,则
打印(“正在尝试连接到AccessPoint…”)
其他的
own_ip,netmask,gateway=wifi.sta.getip()
打印(“连接到访问点:”)
打印(“IP信息:\n此设备的IP地址:”,拥有\u IP)
打印(“网络掩码:”,网络掩码)
打印(“网关地址:”,网关“\n”)
打印(“在浏览器中键入IP地址“.own_IP..”以显示SHT-31-WEB”)
tmr.停止(0)
结束
(完)
计数器=0
srv=net.createServer(net.TCP,28800)
打印(“服务器已创建…\n”)
srv:监听(80,功能(连接)
连接:打开(“接收”,功能(sck,请求)
本地消息={}
计数器=计数器+1
消息[#消息+1]=“”
消息[#消息+1]=“ESP8266 SHT-31 Web服务器版本003”
message[#message+1]=“更多的文字信息”。.计数器..”
本地函数发送(sk)
如果#消息>0,则
sk:发送(表.删除(消息,1))
其他的
sk:close()
消息=零
打印(“堆可用:“…node.Heap())
结束
结束
sck:打开(“已发送”,发送)
发送(sck)
(完)
(完)

您没有告诉我们您使用的固件版本。我在Chromium浏览器中测试了最新版本,没有发现任何内存问题。我在700多个重新加载周期后中止了测试,堆消耗是绝对稳定的

今年早些时候,我们不得不这样做,因为太多处于时间等待状态的废弃套接字正在消耗内存。说明:

等待时间

(服务器或客户端)表示等待足够的时间 要传递,请确保远程TCP收到了对其 连接终止请求。[根据RFC 793,连接可以 等待时间最多为四分钟,称为两分钟 (最大段寿命)。]

资料来源:

更多详情:

然而:

  • 您似乎打算通过HTTP将HTML发送回您的客户机,但不要告诉它,它可能不是这样
  • 如果您的客户端(浏览器?)没有按时关闭旧的套接字,您也可以明确地告诉它这样做
添加适当的HTTP头可以修复这两个问题。因此,消息部分应如下所示:

local message = { "HTTP/1.0 200 OK\r\nServer: NodeMCU on ESP8266\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n" }

counter = counter + 1

message[#message + 1] = "<html><head> <meta http-equiv=refresh content=1; URL=http://" .. own_ip .. "> </head>"
message[#message + 1] = "<body><h1> ESP8266 SHT-31 Web Server Ver 003</h1>"
message[#message + 1] = "<h2>some more text blabla blub" .. counter .. "</h2></body></html>"
local message={“HTTP/1.0 200 OK\r\n服务器:ESP8266上的NodeMCU\r\n连接:关闭\r\n内容类型:text/html\r\n\r\n”}
计数器=计数器+1
消息[#消息+1]=“”
消息[#消息+1]=“ESP8266 SHT-31 Web服务器版本003”
message[#message+1]=“更多的文字内容”。。柜台""

注意
连接:close
内容类型:text/html
以及结构正确的html标记。

我知道根本原因是什么。但首先我建议您删除描述中的历史记录,只描述您当前正在使用的代码(以及AFAIU失败的代码)。