带自动更新功能的NodeMCU超小型Web服务器内存不足

问题描述:

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

如果我一段时间后,即使只有一个客户(我的电脑或智能手机)连接NodeMCU板崩溃与此消息:

惊慌:未受保护的错误调用Lua的API(SO-WebSrv -Test.lua:27:内存不足)

我使用马塞尔Stoer此代码谁在类似的“内存溢出” question回答。

我修改了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) 
+0

我有一个想法是什么根源。但首先我建议你在描述中删除历史记录,并且只描述你目前正在使用的(并且失败的AFAIU)的代码。 –

你没有告诉我们您所使用的固件版本。我在Chromium浏览器中测试了最新版本,但没有发现任何内存问题。经过700多次重新加载循环后,我终止了测试,堆消耗量绝对稳定。

今年早些时候,我们不得不reduce the TCP TIME_WAIT parameter value,因为太多放弃等待状态的窝被吃掉了记忆。说明:

TIME-WAIT

(无论是服务器或客户端)表示等待足够的时间 传递,以确保远程TCP接收其 连接终止请求的确认。 [根据RFC 793的连接可以 留在TIME-WAIT已知为两个MSL (最大段寿命)的最大的四分钟。]

来源:https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Protocol_operation

更多细节:https://tools.ietf.org/html/rfc7230#section-6.6

但是:

  • 你似乎打算通过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>" 

注意到Connection: closeContent-Type: text/html以及在结构正确的HTML标记。