Продолжаем работу с нашим сервером HTTP и на данном уроке для ответа клиенту мы будем использовать функционал библиотеки IDF. Благодаря данной библиотеке нам не придётся писать код для многих рутинных процессов, присущих протоколу HTTP.
Схема наша, как и в прошлом занятии, будет состоять только из отладочной платы с контроллером ESP32, подключенной к USB-порту компьютера
Проект мы будем использовать из прошлого урока с именем WIFI_STA_HTTP_SERVER и присвоим ему имя WIFI_STA_HTTP_SERVER_IDF.
Откроем проект в Espressif IDE и в функции app_main файла main.c удалим строку с созданием задачи для сервера, так как она нам будет не нужна и сервер будет запускаться несколько по-другому
xTaskCreate(http_task, "http_task", 4096, NULL, 5, NULL);
В файле http.c также удалим функцию данной задачи http_task вместе с телом, не забывая также о прототипе в заголовочном файле.
Объявления глобальных массивов http_header, index_htm и favicon_ico также удалим, мы их добавим позже, так как в них будут некоторые изменения.
В заголовочном файле http.h удалим подключение библиотек отвечающих за работу со стеком протоколов
#include "lwip/err.h"#include "lwip/sockets.h"#include "lwip/sys.h"#include <lwip/netdb.h>
Подключим библиотеку для работы с протоколом http
Вернёмся в файл http.c и добавим функцию, которая будет запускать наш сервер
Ниже добавим функцию, которая будет сервер останавливать
Объявим прототипы для обеих этих функций в заголовочном файле http.h, а в заголовочном файле wifi.h подключим данный заголовочный файл
В функции wifi_start в файле wifi.c объявим переменную типа указателя на экземпляр HTTP-сервера
Далее при регистрации обработчиков передадим в параметрах указатель на нашу переменную
ret = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, &server);
...
ret = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, &server);
В функции on_got_ip получим наш указатель и, предварительно убедившись, что сервер не запущен, вызовем функцию запуска сервера
А в функции on_wifi_disconnect аналогичным образом мы наш сервер остановим
Вернёмся в файл http.c и в функции start_webserver объявим и инициализируем по умолчанию переменную типа структуры для конфигурации сервера HTTP, а также включим опцию очистки наименее использующихся соединений
Выше функции start_webserver добавим функцию-обработчик для обработки события запроса сервером главной страницы (ввод в браузере только адреса сервера)
Узнаем длину заголовка в запросе, увеличив её сразу на 1 для завершения нулём
Скопируем заголовок в буфер и выведем его в лог, затем освободим память, запрошенную под буфер
Объявим локальный указатель и присвоим ему адрес контекста из входного параметра
Объявим и инициализируем глобальный строковый массив с содержимым главной страницы, причём прямо в текстовом виде без всякого заголовка, заголовки формирует библиотека
Вернёмся в функцию all_get_handler и отправим нашу страницу клиенту
Убедимся в отсутствии других запросов, попытавшись прочитать заголовок
Надо нам теперь наш обработчик как-то зарегистрировать. Для этого ниже него объявим и инициализируем переменную типа структуры идентификатора ресурса (URI)
А в функции start_webserver попытаемся запустить сервер. Если всё нормально, то здесь мы и зарегистрируем наш обработчик и выйдем из функции с возвратом указателя на экземпляр сервера
А для иконки объявим бинарный глобальный массив
Ниже функции all_get_handler добавим аналогичный обработчик для запроса иконки, хотя, в принципе, можно было бы объединить всё в одном запросе, но в разных, я думаю, будет понятнее и нагляднее
Пока в теле находится только аналогичный код, а дальше уже будут расхождения.
Сначала установим в заголовке тип передаваемого документа, так как по умолчанию текстовый
А далее поступим как с обычным текстом, присвоив указатель и передав аналогично пакет клиенту
И далее аналогично проверим отсутствие других запросов, попытавшись прочитать заголовок
Выше функции start_webserver объявим и инициализируем переменную типа структуры идентификатора ресурса (URI) для иконки
В функции start_webserver зарегистрируем и этот обработчик
В принципе, можем начать проверку.
В конфигураторе у нас ничего не меняется, поэтому можем ничего не настраивать.
Соберём проект, прошьём контроллер и в терминале узнаем сетевой адрес платы
Запустим Wireshark, отфильтровавшись по данному адресу, и попробуем сделать запрос главной страницы в браузере
Всё отлично! Страничка загрузилась и иконка, как видим, тоже.
Посмотрим обмен в Wireshark
Здесь также всё соединяется и разъединяется.
При закрытии браузера происходит окончательное разъединение с портом
Итак, сегодня нам удалось модифицировать наш HTTP-сервер. Теперь он работает с использованием функционала комплекта IDF.
Всем спасибо за внимание!
Оригинал статьи находится здесь.
<<Предыдущий урок | Следующий урок>>
Недорогие отладочные платы ESP32 можно купить здесь
Недорогие отладочные платы ESP32/ESP32-C3/ESP32-S3 можно купить здесь
Логический анализатор 16 каналов можно приобрести здесь
Многофункциональный переходник CJMCU FT232H USB к JTAG UART FIFO SPI I2C можно купить здесь
Видео в Rutube
Видео в Дзен
Видео в Youtube