Отправьте весь 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 и складывания данных на страницу.