2017-09-17 11 views
-1

자동 업데이트 기능이있는 약간의 Lua 웹 서버를 테스트하고 있습니다. HTML 코드가 매초마다 웹 서버로 리디렉션됩니다. 따라서 클라이언트의 웹 브라우저는 항상 브라우저의 캐시를 사용하여 대신 서버에서 새 데이터를 가져옵니다.NodeMCU 자동 업데이트 기능이있는 초소형 웹 서버가 메모리가 부족합니다.

나는 몇 시간 후에도 하나의 클라이언트 (내 PC 또는 스마트 폰)로 연결하는 경우이 메시지와 함께 NodeMCU 보드 충돌 :

PANIC : 루아 API (에 대한 호출에서 보호되지 않은 오류 SO-WebSrv -Test.lua : 27 : 메모리 부족)

나는 비슷한이 question "메모리 부족"에 대답 마르셀 Stoer에서이 코드를 사용했다.

Marcel 's 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에 실패한 코드를 제안합니다. –

답변

1

당신은 당신이 무엇을 사용 펌웨어 버전을 말해주지 않았다. Chromium 브라우저에서 최신 버전을 테스트했지만 메모리 문제가 발생하지 않았습니다. 나는 700+ 리로드 사이클 후에 테스트를 중단했다. 힙 소비는 절대적으로 안정적이었다.

올해 초에 우리는 reduce the TCP TIME_WAIT parameter value을 사용해야했습니다. 너무 많은 버려진 소켓이 시간 대기 상태로 유지되어 메모리를 다 먹어 버렸기 때문입니다. 설명 :

(서버 또는 클라이언트)가 충분한 시간 기다리고 나타냅니다 TIME-WAIT 원격 TCP가 연결 종료 요청의 승인을받은 확실하게 전달합니다. [RFC 793에 따르면, 연결에 체류 두 MSL (최대 세그먼트 수명)으로 알려진 사분의 최대 시간은 잠깐있다.]

자료 : https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Protocol_operation

더 상세 : https://tools.ietf.org/html/rfc7230#section-6.6

그러나 :

  • 당신은 그렇게하지 않을 수 있습니다, 당신의 클라이언트로 HTTP를 통해 HTML을 전송하려는 것 같다하지만 말하지 마 클라이언트 (브라우저가?) 시간에 이전 소켓을 닫습니다하지 않는 경우
  • 당신은 또한 모두 그렇게 명시 적으로

할 적절한 HTTP 헤더를 추가하도록 수정 말할 수 있습니다.따라서, 메시지 부분은 다음과 같이해야합니다 :

Connection: closeContent-Type: text/html
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>" 

를 적어 둡니다뿐만 아니라 제대로 구조화 된 HTML 마크 업.