NodeMCU Web-server

Большинство найденных в интернете примеров веб-серверов для NodeMCU написанных на Lua - это примеры простых статических страниц с отсутствием возможности "одновременной" загрузки доп. файлов css, js, и т.д. Как правило, html код встраивается непосредственно в скрипт, в результате этого занимает место в памяти. Из найденных примеров веб-серверов, которые более менее соответствовали моим требованиям это nodemcu-httpserver, но он громоздкий, съедает много памяти и есть ряд трудностей в работе с ним. Хотелось что-то оптимальное между базовым функционалом и производительностью, так я начал изобретать свой "велосипед".

Была поставлена задача для проекта:

  1. Написать основной код (шаблон, для будущих проектов).
  2. Написать базовую HTML страницу, стили (css) и обработчик (js).
  3. Добавить возможность настраивать модуль с HTML страницы.

От веб сервера требовалось:

  1. Возможность загрузки доп. файлов (js, css, ico,txt,jpg).
  2. Минимальный размер кода в памяти, в режиме ожидания.
  3. Возможность включение LUA кода в HTML страницу.
  4. Запуск LUA скриптов и передача им параметров по средствам POST и GET запросов.
  5. Минимальная аутентификация.
  6. Возможность загрузки сжатых файлов (.gz).

Структура.

Следуя поставленным задачам появилась вот такая структура проекта.

Инициализация:

  • init.lua - инициализации настроек и wi-fi.
  • init_settings.lua - получение настроек, так же хранятся настройки по умолчанию.
  • init_wifi.lua - подключение к wifi сети.

Сервер состоит из четырех основных скриптов:

  • web.lua - сам веб сервер.
  • web_request.lua - разбор ответов от клиента.
  • web_file.lua - передача файлов, запуск скриптов и загрузка html страниц с кодом lua.
  • web_control.lua - аутентификация, сохранения параметров, получения списка точек доступа.

Файлы:

  • favicon.ico - иконка.
  • index.html - главная страница.
  • settings.html - страница настроек.
  • login.html - страница аутентификация.
  • script_settings.js.gz - js скрипт (сжатый) для обработки и отправки форм.
  • style.css.gz - файл стилей (сжатый).

Описание и установка.

Для работы веб сервера потребуются модули (crypto, file, GPIO, net, node, SJSON, timer, UART, WiFi ), далее можете добавить нужные вам. Как собрать прошивку, прошить и залить скрипты, я уже писал. После того как это было сделано можно запускать модуль. При первом старте модуль запустится в режиме точки доступа, через Wi-Fi нужно подключиться к открытой точки доступа с названием "ESP-XXXXXX". Как подключились, заходим в браузер и переходим по адресу 192.168.4.1 . Далее мы попадем на страницу аутентификации, где нужно вести логин и пароль для доступа к модулю, по умолчанию который (логин admin, пароль 0000)

Web интерфейс1

Нас перекинет на главную страницу веб сервера. Это тестовая страница, на ней отображаются данные ESP чипа, количество памяти и список файлов хранящихся на файловой системе чипа. Эту страницу вы можете использовать на свое усмотрение в ваших проектах и также можете создавать свои.

Web интерфейс2

Перейдя по ссылки "Настройки" вы попадете на страницу настроек, на которой можно поменять настройки wi-fi вручную или просканировать сеть нажав на кнопку "Поиск", ниже появится список доступных сетей. Также можно сменить логин и пароль аутентификации или отключить её.

Web интерфейс3

Ограничения.

Сервер обрабатывает файлы по разному, для файлов с расширением .html чтение из файла идет построчное, это сделано для обработки встроенного Lua кода, на размер файла ограничений нет. C файлами с расширением .lua размер отправленных данных не более 4KB. Все остальные файлы передаются побайтно (1024 байт за раз), ограничений на размер файла нет. Сервер не может принимать данные более 1.4KB (данные + заголовок). Пока не было такой необходимости.)))

Пример страницы и добавление в него кода Lua.

Страницу вы можете создать свою или воспользоваться уже готовым шаблоном template.html. В шаблоне подключен файл стилей (style.css.gz), в нем уже есть базовые классы разметки, формы, кнопки и т.д. Подробней можно узнать тут. Фаил стилей постарался сделать как можно компактней (размер в сжатом виде ~ 3кБ).

При добавлении Lua кода в html страницу учитывайте:

  1. Lua код должен быть в одну строку. (Чтение файлов .html идет построчное)
  2. Объем одной строки Lua кода не более 1KB.
  3. Переменные должны быть объявлены как локальные "Local".(Чтобы не засорять глобальное пространство имён)
  4. Глобальные переменные используйте по необходимости, для постоянных значений.
  5. Старайтесь чтобы размер страницы не превышал 5KB (При большем размере увеличится время загрузки страницы).
  6. Для оптимизации и уменьшения размера страницы можно ее сжать, удалив все пробелы и переносы строк, (только помните, что длина одной строки не должна превышать 1KB
<!-- правильно -->
<div class="group">
  <input type="number" id="num" required="" value="<?lua local x = 6 return(x\*2) ?>">
  <label for="num">Number</label>
</div>

<!-- тоже правильно -->
<div class="group"><input type="number" id="num" required="" value="
<?lua local x = 6 return(x\*2) ?>"><label for="num">Number</label></div>

<!-- так тоже работает -->
<input type="number" min="<?lua return(x\_min) ?>" max="<?lua return(x\_max) ?>">

<!-- Не правильно (код не будет обработан, так как есть перенос строк в lua коде) -->
<div class="group">
  <input type="number" id="num" required="" value="
  <?lua x = 6 
  return(x\*2) 
  ?>">
  <label for="num">Number</label>
</div>

Как создавать Lua скрипты для сервера.

Скрипт должен быть в виде функции, которая желательно возвращает текстовое значение или таблицу. Таблица в свою очередь будут автоматически преобразована в JSON, это позволяет взаимодействовать с клиентской частью на JavaScript. При таком подходе к написанию скриптов преследуется две цели. Во первых, нам нужно принять какие-то данные от клиента, обработать их нашим скриптом и передать результат обратно, а иначе зачем нам вообще веб морда и веб сервер. Во вторых, после выполнения такого скрипта, сборщик мусора удалит его из памяти, главное не забывать объявлять все переменные и функции локальными.

Рассмотрим пример с файлом "template.lua". Параметры от GET запроса будут переданы в таблицу args. http://IP/template.lua?key=value&name=CodeDevice

Local function arg_to_str(val)
  local str = ""
  for k, v in pairs(val) do
    str = str..k.." : "..v.."
  end
  return str
end

return function (args)
 return arg_to_str(args)
end

Иногда бывает нужно выполнить какую нибудь асинхронную операцию (которая требует времени на обработку), как например, получение списка доступных wi-fi сетей. Конечно можно зациклить и ждать пока функция отработает, но крайне не желательно так делать. Выйти из положения можно другим путем, при первом запросе запускаем поиск сетей и после того как скрипт отработает он запишет полученные данные в файл, а уже вторым запросом прочитаем эти данные из файла. Так же нужно поступать если хотите получить большой объем данных (>4KB) от Lua скрипта, например результат выполнения записать в файл big_data.txt и вторым запросом получить его. Так как ограничения на чтения файлов (.txt и др.) нет. http://IP/big_data.txt

Советы по оптимизации.

  • Для ускорения загрузки - сжимайте (.gz) текстовые файлы .css, .js, .txt
  • Если в Html страницы нет кода Lua, то ее тоже можно сжать
  • Не делайте частых ( <1 раза в сек) запросов к серверу
  • Для передачи параметров скрипту, давайте предпочтение javascript и POST запросам (запросы выполняются в фоновом режиме, без перезагрузки страницы)
  • Не используйте много контента на странице.

Нужно понимать что ресурсы ESP ограничены и все реализовать в одном проекте не получится, придется чем-то жертвовать.

NodeMCU ESP8266
(0.0) / 0
Прежде чем оставить комментарий, пожалуйста, ознакомьтесь с правилами комментирования. Оставляя комментарий, вы подтверждаете ваше согласие с данными правилами и осознаете возможную ответственность за их нарушение. Все комментарии премодерируются.
0
Рубрики
Свежие записи