NodeMCU: Доступный размер кучи уменьшается до тех пор, пока не будет исчерпана память - PullRequest
0 голосов
/ 29 апреля 2018

У меня возникли некоторые проблемы с моим NodeMCU, работающим на простом сервере в режиме точки доступа, запрограммированным в LUA с использованием ESPlorer.

Вот скрипт LUA:

local SSID = "NodeMCU"
local SSID_PASSWORD = "12345678"

function connect (conn)
   print ("Hello connect")
   conn:on ("receive",
       function (cn, req_data)
           print(req_data)
           print("Available memory :")
           print(node.heap())
           --local query_data = get_http_req (req_data)
           local query_data = {}

           cn:send("HTTP/1.1 200 OK\n\n", 
           function()
               cn:close()
               --collectgarbage()
           end)
      end)
end

-- Configure the ESP as a station (client)
wifi.setmode (wifi.SOFTAP)

cfg={}
cfg.ssid=SSID
cfg.pwd=SSID_PASSWORD
wifi.ap.config(cfg)

cfg={}
cfg.ip="192.168.1.1";
cfg.netmask="255.255.255.0";
cfg.gateway="192.168.1.1";
wifi.ap.setip(cfg)

print("Set up UART config")
uart.setup(1, 921600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)

-- Create the httpd server
svr = net.createServer (net.TCP, 30)

-- Server listening on port 80, call connect function if a request is received
svr:listen (80, connect)

После запуска этой программы на NodeMCU я подключаю свой компьютер в WiFi к NodeMCU и отправляю ему несколько запросов HTTP POST с этим фрагментом кода Java:

public void sendPost(RGBWPixel[][] LedMatrix) throws Exception {

    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

    System.out.println("Sending post");
    // add reuqest header
    con.setRequestMethod("POST");
    con.setRequestProperty("matrixValues", new String(convertTo1DCharArray(LedMatrix)));
    con.setDoOutput(true);


    DataOutputStream wr = new DataOutputStream(con.getOutputStream());
    wr.flush();
    wr.close();

    con.getResponseCode();

}

obj - это соединение URL, соответствующее IP-адресу NodeMCU. Строка, соответствующая matrixValues ​​, всегда имеет длину 2050.

Пожалуйста, обратите внимание, что я сократил LUA srcipt до минимальных функций, которые позволяют решить проблему. Точнее, это происходит, когда у меня была часть cn: send (), но я не знаю, возможно ли получить и обработать запрос без отправки ответа, потому что запрос не отправляется, когда я не запускаю con.getResponseCode () из программы Java. Я новичок в http, поэтому пока не понимаю всех протоколов.

Вот как выглядит вывод со стороны NodeMCU в ESPlorer:

> dofile("init.lua");
Set up UART config
> Hello connect
POST / HTTP/1.1
matrixValues: 
Available memory :
38088

Available memory :
37032
Hello connect
POST / HTTP/1.1
matrixValues: 
Available memory :
37688

Available memory :
36664
Hello connect
POST / HTTP/1.1
matrixValues: 
Available memory :
37440

Available memory :
36264

И после нескольких десятков итераций это происходит, и NodeMCU перезапускается:

Hello connect
POST / HTTP/1.1
matrixValues: 
Available memory :
4680

Available memory :
3600
E:M 1584
PANIC: unprotected error in call to Lua API (init.lua:19: out of memory)

ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 26704, room 16 
tail 0
chksum 0x0c
load 0x3ffe8000, len 2184, room 8 
tail 0
chksum 0x9a
load 0x3ffe8888, len 136, room 8 
tail 0
chksum 0x44
csum 0x44

Строка 19 соответствует строке cn: send (). Я предполагаю, что сделал что-то не так, объявив некоторые переменные, функции или функции обратного вызова в сценарии LUA, этот стек, пока нет больше памяти ... Кроме того, я не понимаю, почему есть 2 вызова функции conn: функция обратного вызова (где печатается node.heap ()) только для одного «Hello connect». Это как второй пустой запрос http всегда отправляется ...

Большое спасибо за ваше драгоценное время и вашу потенциальную помощь, если вы пришли к концу этого поста!

Пол

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Отправьте заголовок:

Connection: close

С обоими запросами и ответами. По умолчанию для современных http-серверов и клиентских приложений используется поддержка активности. Когда этот заголовок присутствует, другая сторона явно закроет соединение, когда все данные будут отправлены. Когда соединение закрывается, память освобождается.

0 голосов
/ 29 апреля 2018

sck:send(data, fn) эквивалентно sck:send(data); sck:on("sent", fn).
Закрытие, переданное в :on(), должно , а не , напрямую ссылаться на объект ( объяснения ).
Используйте первый аргумент функции обратного вызова вместо ссылки на верхнее значение.

cn:send(
   "HTTP/1.1 200 OK\n\n", 
   function(s)  -- s here has the same value as cn
      s:close()
      --collectgarbage()
   end
)
...