Отправьте весь HTML-код с клиентом:send() в программе Nodemcu Esp8266 lua

Я создал файл lua, который реализует модуль 2relay для управления рольставнями через веб-сайт.
Я последовал примеру led_webserver и расширил свой код оттуда.
Я пробовал так много способов отправить полную HTML-страницу с функцией client:send(),
но это не похоже на работу.


Это страница, которую я сам разработал, и она работает на ПК, но я не смог найти простой способ отправить ее.
Я объявляю локальную переменную (например, test), которая содержит весь HTML-код, а затем помещаю ее в качестве параметра в `client:send(test).
Кто-нибудь знает другой способ сделать это?

5 ответов

Стек TCP на eps8266 не поддерживает потоковую передачу по IP-пакетам. Каждая отправка может быть до одного полного IP-пакета, но длиннее, и вы отправляете их пакет за пакетом, используя soc:on("sent",callback), См. Неофициальный FAQ для более подробной информации об этом.

Другие постеры дали много хорошей информации, но я не думаю, что было дано хорошее конкретное решение этой проблемы, даже в неофициальном FAQ.

Чтобы отправить большие статические файлы, вы можете загрузить их из флэш-памяти и отправить их порциями, используя обратные вызовы. Как уже упоминали другие люди, существует предел того, сколько можно отправить одним звонком. А несколько вызовов отправки в одном обратном вызове могут не обрабатываться так, как вы ожидаете, и могут занимать слишком много памяти. Вот краткий пример загрузки и отправки файла кусками:

local idx = 0 --keep track of where we are in the file
local fname = "index.html"

function nextChunk(c) --open file, read a chunk, and send it!
      file.open(fname)
      file.seek("set", idx)
      local str = file.read(500)
      if not str then return end --no more to send. 
      c:send(str)
      idx = idx + 500
      file.close() --close the file to let other callbacks use the filesystem
end
client:on("sent", nextChunk) --every time we send a chunk, start the next one!
nextChunk(client) --send the first chunk. 

или, используя сопрограммы и таймер, мы можем сделать его более гибким:

local ready = true --represents whether we are ready to send again
client:on("sent", function() ready=true end) --we are ready after sending the previous chunk is finished.

local function sendFile(fname)
    local idx=0 --keep track of where we are in the file
    while true do
        file.open(fname)
        file.seek("set", idx)
        local str = file.read(500)
        if not str then return end --no more to send. 
        c:send(str)
        ready=false --we have sent something. we are no longer ready.
        idx = idx + 500
        file.close() --close the file to let other callbacks use the filesystem
        coroutine.yield() --give up control to the caller
    end
end

local sendThread = coroutine.create(sendFile)
tmr.alarm(0, 100, 1, function() --make a repeating alarm that will send the file chunk-by-chunk
    if ready then coroutine.resume(sendThread, "index.html") end
    if coroutine.status(sendThread) == "dead" then tmr.stop(0) end --stop when we are done
end)

Я нашел простое решение для этого. Мне пришлось отправить большой файл, содержащий текст, и я использовал для этого следующий код:

    file.open("example.txt","r") 
    for counter=1, numboflinesinfile-1 do
    client:send(file.readline() .. "<br>");  
    end           
    file.close()

counter - это просто переменная подсчета numberoflines, если число строк, которое вы хотите отправить.

Не чистое решение и, возможно, нарушающее все правила программы, но работающее как шарм.

Вы можете использовать следующее:

    buf = "<h1> ESP8266 Web Server</h1>";
    buf = buf.."<h2>Subtitle</h2>";
    client:send(buf);

Отправка более двух сотен байтов за один вызов чаще всего дает сбой. Также следует понимать, что несколько последовательных вызовов для отправки в пределах одного и того же фрагмента lua ставятся в очередь и выполняются асинхронно после возврата фрагмента - это потребляет непрактичные объемы памяти.

Поэтому создание страницы любой сложности с конкатенацией значений времени выполнения проблематично. Более рациональный подход для ESP8266 - просто возвращать данные в формате JSON и обслуживать модные страницы с ПК со встроенным скриптом для запроса ESP и складывания данных на страницу.

Другие вопросы по тегам