Web сервер на несколько одновременных соединений
- Войдите на сайт для отправки комментариев
Наконец доделал (в свободное время) сервер на esp8266, примерно выглядит так
WiFiServer server(80); WiFiClient client; // подразумеваем, что у нас будет только одна сесия void loop() { LoopReadUart(); if (client) { if (time_pause(time_loop_new, millis()) > 10000) { // держим не более 10 сек client.stop(); clear_param_wifi(); } } if (!client) { // попытка создание клиентской сессии client = server.available(); if (client) { time_loop_new = millis(); } } if (client) { LoopReadWiFi(); } }
Но он работает только для одной сессии, в инете почти все примеры сделаны аналогичны.
Нужно сделать на несколько сессий, как пример есть например вот ссылка на https://github.com/esp8266/Arduino/issues/307 примерчик, но меня смущает статическое выделение памяти сразу на максимум сокетов. С другой стороны динамическое выделение может привести к сильной сегментации (по сколько куски большие на буфер данных должны выделятся) памяти и периодическому ребуту.
Если у кого есть примеры реализации мультиклиентского сервера подтолкните :)
ну и второй вопрос - как сделать авторизацию, в теории я знаю пару способов, но хотелось-бы конкретику глянуть, да я понимаю, что на клиенте нужно хранить или куку или параметр сесии (и это у меня уже реализовано) а вот как сделать относительно безопасно передачу этого значения с сервера на клиент? и какой по составу он должен быть?
espasyncwebserver + tls
//Если у кого есть примеры реализации мультиклиентского сервера подтолкните :)
Подталкиваю. Не делай так.ESP и с одним клиентом дышет еле. Если светить в внешний мир портом, то большой разницы сколько клиентов поддержать нету. Нехватит по любому. А в локалке и один клиент достаточен.
32 еспешка нормально дышит и решение есть, но не такое короткое как в примере.
Она конечно помощней, но и для нее вроде тоже пишут до 5 подключений. Хоть я лично не пробовал 32-ю.
сделал на 5 подключений, любое выше 5 подключений выдает страницу 503, правда пока не смог проверить на превышение, реально проверял только на 3х параллельных устройствах.
работает вообще шикарно.
осталось авторизацию добавить и будет мне счастье :)
пока вот так
А MAX_SRV_CLIENTS у тя наверно 5.
//работает вообще шикарно.
угу. Пока пустой. Там куча общая и для ТСР стека и для приложения. Просекаеш? Добавь где client.print("Free RAM="); client.print(ESP.getFreeHeap()); и следи за процессом.
Кстати, че будет выдавать эта getFreeHeap() - пиши сюда, всем интересно.
обязательно отпишусь, но позже...
немного поигрался с 2х паралельных сессий
вывод памяти происходит только при отправки данных сервером на клиент
Она конечно помощней, но и для нее вроде тоже пишут до 5 подключений. Хоть я лично не пробовал 32-ю.
Это ограничение ее как точки доступа. Но ее ресурсы естественно не бесконечны.
немного поигрался с 2х паралельных сессий
вывод памяти происходит только при отправки данных сервером на клиент
Давай разницу при одном клиенте и при двух, трех одновременных ..
У меня щас Free RAM=26040Б;. При одном клиенте. И тоже скачет- туда сюда на пару КБ. В моем софте есть таблица измерение на 12КБ, лог на 5КБ, sntp , OneWire, обвязка на 3 датчика ds18b20, еще чего по мелочам ... По наблюденям падает прога когда Free RAM к 20КБ подходит. Это экспертная оценка, последнее значение не видно)) И это изредка случается, пару раз в неделю дето.
Я понемногу "откусывал" ОЗУ от кучи себе, пока не пришел к нестабильности. Когда Free RAM выдавало 28-30КБ все было ОК, месяцами работало.
Так понимаю, когда в стеке протокола проблемы, например битые пакеты приходят, или их порядок нарушается, памяти надо больше. Пакет считаем 1,5КБ плюс по мелочам, это для одного клиента. Не от того ли скачет Free RAM на пару КБ? А если проблема сразу у 5 клиентов?
//вывод памяти происходит только при отправки данных сервером на клиент
Ну все так делают. Вот ща задумался. Можно ведь ловить минимальное значение, каждый проход Loop, выдавать клиенту его при отправки данных сервером.. Ща допилю...
Она конечно помощней, но и для нее вроде тоже пишут до 5 подключений. Хоть я лично не пробовал 32-ю.
Это ограничение ее как точки доступа. Но ее ресурсы естественно не бесконечны.
Вот, предлагаю, в этой теме совместными усилиями и прояснить как далеко от реальности до бесконечности )))
Не, все зависит от структуры сервера и объема данных. Мы этого не знаем. Смысла нет.
у меня разницы при клиентах почти нет, я сделал по схеме статического массива, туда воткнул все переменные которые привязаны к сессии,
память скачет примерно в диапазоне 5...6 килобайт
При этом у меня каждые 5 сек json отрабатывает, получает данные.
на самой есп (а она у меня практически без пинов esp-01s) есть только
обмен по UART с НАНО, именно на НАНО заведены датчики
чтение с файлов из собственного флеша куда и залита страница и отдельно файл с настройками (паролями и т.д.)
и собственно WEB
к такой конфигурации я пришел через простой вывод, лучше 2 контроллера которые будут друг друга мониторить и перегружать по необходимости чем один заткнется... Мониторинг пока не сделал...
Плавание кб обьясняестя просто
1. я использую String, он динамит.... в планах есть отказаться от него совсем, у меня остался последняя функция с ним.
2. буферы сервера, они то же динамические, тут все просто - их надо чистить быстрее чем они растут
вот мой сервер
Пока клиенты отваливаются примерно через 10 мин. Наверно это внутренний таймаут. Но сервер при этом работает, если страницу обновить, то все сново работает.
И кстати пока никаких перезагрузок
добавил кусочек для отслеживания количества активных сессий (пока играюсь с пределом в 4шт)
вот результат, там где + это активная сессия, и кстати даже для одного реального сеанса открывается иногда и по 2 сессии, судя по всему это параллельная скачка файлов, и реально шустрее работает
в библиотеке есть константа
MAX_PENDING_CLIENTS_PER_PORT=5
ее можно переопределить на большее число, но надо смотреть за памятью.
вроде как на значение в 5 сесий памяти должно хватать
в библиотеке есть константа
MAX_PENDING_CLIENTS_PER_PORT=5
ее можно переопределить на большее число, но надо смотреть за памятью.
Так собственно в том и вопрос. Как только начнет расти LoopReadWiFi, то все что в ней выделится надо умножать на 5. LwIP какой версии? Если 2.0 то она проблемная. Например http://arduino.ru/forum/apparatnye-voprosy/polzuet-li-kto-wifi-moduli-esp8266-podelites-vpechatleniyami?page=23#comment-559687 А 1.4 памяти больше требует.
Надо понимать, что количество сессий и количество клиентов - это разное. Один клиент может жрать и 5 сессий...
я это реально наблюдал, тут самое главное - это ассинхронно обрабатывать все открытые сессии, это можно делать или через прерывания или в главном цикле, я пошел вторым путем, он не самый лучший, но более надежный и более простой в понимании (не надо никаких мьютексов и семафоров).
Я разумеется понимаю, что выставить в инет еспшку это просто глупость, а вот например реализовать к ней несколько параллельных веб клиентов это уже интересно.
Лично мне больше 5 клиентов не понадобится, а сесси реально долго не живут и освободожаются быстро.
Хотя есть тут какая-то фигня когда он перестает нормально отвечать на JSON, при этом сессия создается и сразу рубится, но где именно рубится я пока не понял.
Короче судя по всему лично мне функционала на 5 клиентов вполне хватает. Я пока буду копать в сторону стабильности и авторизацию доделаю.
Потом наверно весь труд задокументирую и выложу в "проекты" или еще куда
Думаю пока сделать несколько параметров (в процентах) которые будут отображать
1. загрузку параллельных соединений (1 соединение = 20%)
2. загрузку памяти (60к свободной = 0%, 10к свободной = 100%)
3. и так далее, что еще мне понадобится не знаю
Чем с протокольной/программной точки зрения измерения в клиентах лучше измерения в сессиях? Какой смысл вообще измерять в клиентах?
для меня разницы особой нет, по тому как и клиент и сессия вроде как идентифицируются одинаково IP+Port,
но если копать глубоко - там разница уже будет
Разница в человеческой голове (на прикладном уровне). Вебсерверу должно быть фиолетового.
Но вот считать в клиентах - так же, как и в попугаях. Цифра есть, но смысла нет.
//это можно делать или через прерывания....
У ESP8266 нельзя. С прерываниями там вообще безнадега. Там я ссылку бросал, читай, там дальше и про прерывания.
//60к свободной
это откуда столько то.. 45КБ мелькало там максимум..
//никаких мьютексов и семафоров
отбрось эти пережитки больших машин следом за многопоточностью. Вот то цикл LoopReadWiFi - не просто лучшее. Это единственное по сути.
Не совсем так, клиентский сокет может не порождать клиентской сессии. Тем не менее соединение будет висеть и жрать ресурсы. По этому ограничение которое прописано в библиотеке - это по существу ограничение на ответ сервера а ограничение по сесиям это другое, тут например может возникать ошибка http 503.
Если рассматривать уровень прикладного сервера, то ограничение по клиентам - предназначено в перую очередь для борьбы с ддос атаками, и оно не имеет обрабаботку внутри прикладной части сервера (оно в ядре),
а вот ограничения на сесии - это уже прикладной уровень...