Простой HTTP-сервер
Теперь мы превращаем плату в крошечный веб-сервер, который при получении запроса GET отдаёт данные с внутреннего датчика температуры.
Подготовка
Подготовленная заготовка проекта находится в intro/http-server/. Она уже включает установку подключения к Wi-Fi, но вам нужно настроить её на данные вашей сети в cfg.toml.
intro/http-server/examples/http_server.rs содержит решение. Запустить его можно командой:
cargo run --example http_server
Обработка запросов
Чтобы подключиться к плате из браузера, нужно знать её IP-адрес.
✅ Запустите код заготовки в intro/http-server. В выводе должен появиться IP-адрес платы, примерно такой:
I (3862) esp_netif_handlers: sta ip: 192.168.178.54, mask: ...
...
Server awaiting connection
sta ip — это «station», термин Wi-Fi для интерфейса, подключённого к точке доступа. Это адрес, который вы введёте в браузере (или в другом HTTP-клиенте, например curl).
🔎 ESP-IDF пытается зарегистрировать имя хоста
espressifв вашей локальной сети, поэтому часто работает иhttp://espressif/вместоhttp://<sta ip>/.Имя хоста можно изменить, задав
CONFIG_LWIP_LOCAL_HOSTNAMEвsdkconfig.defaults, например:CONFIG_LWIP_LOCAL_HOSTNAME="esp32c3"
Отправка HTTP-данных клиенту включает:
- создание экземпляра
EspHttpServer; - цикл в функции
main, чтобы она не завершалась: иначе сервер вышел бы из области видимости и остановился; - задание отдельной функции-обработчика
handlerдля каждого пути, по которому нужно отдавать содержимое. Любой не настроенный путь вернёт ошибку404. Эти обработчики реализуются как замыкания Rust прямо в коде:
#![allow(unused)]
fn main() {
server.fn_handler(path, Method::Get, |request| {
// ...
// создаём ответ
let mut response = request.into_ok_response()?;
// теперь можно записать нужные данные
response.write_all(&some_buf)?;
// когда закончите, обработчик ожидает в качестве результата `Completion`,
// это делается так:
Ok(())
});
}
✅ Создайте экземпляр EspHttpServer с конфигурацией по умолчанию esp_idf_svc::http::server::Configuration. Конфигурация по умолчанию автоматически заставит его слушать порт 80.
✅ Проверьте, что подключение к http://<sta ip>/ возвращает ошибку 404 (not found) с текстом This URI does not exist.
✅ Напишите обработчик запросов к корневому пути ("/"). Обработчик отправляет приветственное сообщение по адресу http://<sta ip>/, используя готовую функцию index_html() для генерации HTML-строки.
Динамические данные
Мы также можем передавать клиенту динамическую информацию. Заготовка включает настроенный temp_sensor, который измеряет внутреннюю температуру платы.
✅ Напишите второй обработчик, который отдаёт температуру чипа по адресу http://<sta ip>/temperature, используя готовую функцию temperature(val: f32) для генерации HTML-строки.
💡 Чтобы отправить строку ответа, её нужно преобразовать в срез &[u8] через a_string.as_bytes().
💡 Датчику температуры нужен эксклюзивный (изменяемый) доступ. Передать его в обработчик по значению не получится: он будет уничтожен после первого вызова. Это решается так: сделайте обработчик замыканием move || и оберните датчик в Arc<Mutex<_>>; один clone() этого Arc останется в функции main, а другой переместите в замыкание.
Устранение неполадок
httpd_txrx: httpd_resp_send_errможно исправить перезапуском, а если ничего не помогает, — командойcargo clean.- Убедитесь, что ваш компьютер и Rust ESP Board подключены к одной и той же сети Wi-Fi.