Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Простой 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.