• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ESP8266 как веб-сервер и клиент mqtt

Melandr

Member
Добрый день! Делаю устройство для управления кондиционером, путем эмулирования пульта ДУ кондиционера. На ESP поднят веб-сервер, работающий в локальной сети и mqtt-клиент, подключенный к облачному MQTT-брокеру. В принципе все работает, но есть одна проблема. Когда открыта веб-страница, при изменении параметров кондиционера через mqtt, не обновляется картинка на странице. Сама ESP обрабатывает входящие запросы от веб-клиента посредством обработчиков
server.on("/state", HTTP_GET, handleGetState);
и аналогичных.
Но если изменения состояния кондиционера происходит по mqtt, то эти изменения не отображаются на html-странице. Максимум до чего додумался, добавил setInterval для get-запроса в js на странице и каждую секунду запрашиваю состояние ESP. Но считаю это сделано не по феншую. По логике, ESP должна сама при изменении состояния отправить post-запрос на страницу с обновленными данными. Но в коде библиотеки ESP8266WebServer.h я не нашел методов, которые бы это делали. Возможно необходимо отслеживать, когда подключается веб-клиент к ESP и потом по изменению состояния ESP отправлять запрос с измененными данными. Но такого функционала не нашел. Подскажите, какие есть варианты реализации? Асинхронный веб-сервер и ws не предлагать, так как времени переделки проекта нет. Хотелось реализовать такой функционал с существующей библиотекой. Заранее спасибо!
 

CodeNameHawk

Moderator
Команда форума
Когда открыта веб-страница
После открытия страницы, она больше не запрашивает данные.
Есть технология, что страница, с задаваемой периодичностью опрашивает сервер и обновляет выбранные данные на странице.
Второй вариант, в html есть параметр, который заставляет перезагрузиться всю страницу, просто, но визуально неприятно.
https://www.geeksforgeeks.org/how-to-automatic-refresh-a-web-page-in-fixed-time/
 
Последнее редактирование:

Melandr

Member
После открытия страницы, она больше не запрашивает данные.
Есть технология, что страница, с задаваемой периодичностью опрашивает сервер и обновляет выбранные данные на странице.
Я так и сделал, добавил в js функцию setInterval с функцией обновления данных (ajax запрос). Просто не понравилось, что запрос проходит, допустим, каждые 2 секунды, и соответственно сеть нагружается, при том что данные не меняются на странице. Думал, может есть какая-то возможность отправить обновленные данные на страницу, только когда они изменятся. Но насколько я понял, в этом случае ESP будет клиентом, Есть httpclient в библиотеках ESP. может нужно его использовать? Когда допустим к серверу подключен клиент и открыта страница, приходят обновленные данные, запускается httpclient и отправляет данные на эту страницу. Или я чего-то неправильно понимаю?
Второй вариант, в html есть параметр, который заставляет перезагрузиться всю страницу, просто, но визуально неприятно.
Такой вариант вообще не рассматриваю, совсем не то...
 

CodeNameHawk

Moderator
Команда форума
Но насколько я понял, в этом случае ESP будет клиентом
Неправильно. Есп веб сервер.
Тут как в обычной библиотеке, запросили, получили книгу с текстом, а в библиотеке текст в книге поменяли, но в полученной книге он от этого не поменяется.
 

CodeNameHawk

Moderator
Команда форума
Просто не понравилось, что запрос проходит, допустим, каждые 2 секунды,
Не понравилось чем?
У меня запрос каждые три секунды, не наблюдаю проблем, даже когда одновременно работают при устройства.
Там передается только короткий JSON или XML набор данных.
А вот с работой MQTT не подскажу, у меня отсылает в базу данных и только если она (база данных) сильно "лагает" бывают проблемы ввиде задержки обновления данных на странице.
 

CodeNameHawk

Moderator
Команда форума
Есть websocket но будет работать от сервера к клиенту, только если все время держать канал открытым, ну или когда откроете канал по новой, но это уже будет как в AJAX.
 

pvvx

Активный участник сообщества
Но если изменения состояния кондиционера происходит по mqtt, то эти изменения не отображаются на html-странице.
Это возможно реализовать только через постоянное соединение с websocket.
И тогда без разницы с какой стороны происходит инициатива. Для клиента это может быть запрос, а для сервера - сам посылает когда надо.
 

pvvx

Активный участник сообщества
Но при многопользовательской реализации сервера на ESP будут проблемы по кол-ву одновременно открытых соединений. Игрушка она и есть игрушка...
 

Melandr

Member
А такой вопрос, а просто отправить ответ с данными от сервера, без запроса со стороны клиента? Такое не возможно сделать?
C:
//обработчик http_get запроса
void handleGetState() {
  if (!server.authenticate(www_username, www_password)) {                           //Если НЕ верно введены или просто НЕ введены Логин/Пароль, тогда...
    return server.requestAuthentication(DIGEST_AUTH, www_realm, authFailResponse);  //...вернуться и повторить попытку ввода.
  }

  DynamicJsonDocument root(256);
  root["mode"] = acState.operation;
  root["fan"] = acState.fan;
  root["temp"] = acState.temperature;
  root["power"] = acState.powerStatus;
  String output;
  serializeJson(root, output);
  server.send(200, "text/plain", output);
}
Вот обработчик get-запроса
Как можно отправить данные которые передаются в строке output не как ответ, а допустим это будет post-запрос с данными от сервера? А клиент ответит, если получил, что все ок. Просто насколько я понял, на ESP обрабатываются входящие запросы. Или только использование ws?
 

pvvx

Активный участник сообщества
А такой вопрос, а просто отправить ответ с данными от сервера, без запроса со стороны клиента? Такое не возможно сделать?
Такой возможности в WEB нет.
Web cервер отвечает только на запросы клиента.
 

pvvx

Активный участник сообщества
Даже в викопедии описано:
Веб-серверсервер, принимающий HTTP-запросы от клиентов, обычно веб-браузеров, и выдающий им HTTP-ответы, как правило, вместе с HTML-страницей, изображением, файлом, медиа-потоком или другими данными.
 

pvvx

Активный участник сообщества
Согласовав TCP соединение клиент засылает запрос, сервер отвечает. TCP cоединение после ответа может быть разорвано, если соединение не "keep alive" или была ошибка.
При "keep alive" сервер после ответа ждет нового запроса на том-же TCP соединении и отвечает...
Если что-то пошлет сервер клиенту - клиент не знает что это и куда это - будет ошибка (и вероятно разрыв текущего TCP соединения).
И куда послать серверу ваши неизвестные данные если TCP соединения нет?
 
Последнее редактирование:

pvvx

Активный участник сообщества
Для ускорения загрузки страниц любой современный браузер сразу открывает от 4-х TCP соединений к серверу для загрузки несколькими потоками разных ресурсов указанных в тексте HTML страницы.
Если пользователь открывает ещё одну страницу с данного сервера - это ещё плюс от 4-х TCP соединений.
Т.е. нормальный web-сервер должен обладать возможностью держать минимум к сотни соединений, что невозможно в убогой ESP. Там всё урезано и ESP не соблюдает никакие стандарты...
 
Сверху Снизу