Всем привет!

Данная статья является первой частью моего туториала по разработке достаточно необычного WSGI сервера. В данной статье я поясню теоретическую часть своей задумки.

Основная аудитория — начинающие разработчики, знакомые с Python но желающие познать дзен работы http протокола.

Готовы? Пошли под кат.

Intro


Да, данная статья является текстовым сопровождением к моему видео (я пытаюсь вести видеоблог). Если интересно — видео на Youtube.

Вам никогда не приходила идея написать такую программу, которую еще никто не писал? Что-то до безумия уникальное, абсолютно (или близкое к абсолютному) бесполезное, но интересное?

Нет? Ну слава богу, меня читают нормальные люди.

А я задумал уникальный и очень интересный проект, реализация которого позволит мне и читателю понять на практике как на самом деле работает http и веб сервера. Данный проект окунет читателя в мир безумия http спецификации, парадокса регулярных выражений и несовершенства драйверов :-). Что позволит тебе познать всю боль низкоуровневой разработки и радоваться простым тупым требованиям пользователя

К стати, возможно ты будешь удивлен но идея данного проекта родилась не на пустом месте. Дело в том, что у меня есть Raspberry PI Zero без вайфая и NodeMCU с wi-fi. Вот я задумался — а можно ли написать веб сервер на Django и захостить на Raspberry PI при этом подключаясь к сети по Wi-Fi. Нормальному человеку пришла бы в голову мысль либо купить малинку с Wi-Fi либо подключить Wi-Fi адаптер к малинке. Мне же пришла в голову идея подключить ESP8266 к малинке, но так как ESP8266 не может работать в качестве сетевого адаптера мне и пришла в голову данная мысль.

Фух, надеюсь оправдался. Теперь к сути

Теория


Веб сервер это достаточно сложная штука, которая работает на низком уровне с сокетами, парсит сырые http запросы разбирая заголовки, управляет соединениями, балансирует нагрузку и т.д. И этот сложный модуль лучше держать отдельно т.к веб приложение уже оперирует более высокоуровневыми понятиями моделей, контроллеров и вьюх. Оба компонента нужны и важны для работы веба, но области знаний, необходимые для их разработки пересекаются не сильно, поэтому лучше им о друг друге знать как можно меньше.

Как известно, существует множество совместимых с написанными на Python веб приложениями серверов (Gunicorn, Bojern, CherryPy лишь не многие из них).

Также как и существует множество веб фремворков, которые могут работать с любым из этих веб серверов.

Как же так получается? Все просто — нам нужен стандарт и этот стандарт зовется WSGI

image
Рис 1 WSGI

WSGI является частью PEP спецификации и позволяет использовать различные фреймворки и веб приложения почти не заботясь о их совместимости.

А указанная ниже иллюстрация прекрасно демонстрирует мою задумку веб сервера на Python

image

Рис 2

Читатель мог заметить на картинке ESP8266 — нет, я не буду размещать веб сервер на данном девайсе, так как по сравнению с моей задумкой это было бы слишком банально.

ESP8266 прошит заводской AT прошивкой, и принимает только AT команды. Но самое главное — при помощи AT команд он может поднять sosket север, который будет принимать http запросы от клиента (получать по WiFi) и транслировать их по serial порту

По серийному порту ESP передает 2 важных параметра — ID сокета, указывая который мы будем возвращать клиенту ответ. ESP8266 к слову поддерживает максимум 4 одновременных подключения по сокетам. И конечно же http запрос

Наш написанный на python 3 веб сервер парсит http складывая заголовки в специальный объект environment и поднимает объект приложения передавая ему метод start_response с помощью которого наше приложение вернет респонс и словарь environment который содержит все необходимые заголовки и тело http запроса (необходимые методы и необходимые ключи словаря environment являются ключевой частью WSGI спецификации)

После того как фремворк выполнит обработку запроса и формирование ответа он дергает метод start_response, в данном методе мы получаем нужные для формирования http ответа параметры, выполняем сборку сырой html строки и передаем по серийному порту в ESP8266
ESP8266 в свою очередь транслирует все это дело клиенту

То, как правильно прошить ESP8266 AT заводской прошивкой я нашел в прекрасной статье, ссылку на которую вы найдете под номером 2 в разделе «Полезные URL»

По AT командам общение с ESP8266 выглядит следующим образом (при общении использую оболочку ESPloter) Также предполагаю что в ESP8266 поднят WiFi. Если Wi-Fi не поднят — это также легко сделать через ESPloter

  1. Команда AT+CIPMUX = 1 — открывает множественное подключение
  2. Команда AT+CIPSERVER=1,80 (80 порт, который мы открываем)

После ввода этих команд мы подняли TCP сервер на ESP8266 и можем получать запросы от клиента.

Возвращаем ответ клиенту также 2-мя командами

— Команда AT+CIPSEND = номер сокета, количество байт
После выполнения данной команды терминал будет ждать сообщение заданного количества байт
Когда мы введем достаточно символов сеанс передачи прекратится и мы должны будем ввести новую команду

AT+CIPCLOSE= номер сокета.

После этого браузер завершает сеанс и отображает переданный текст

На сегодня все. Надеюсь в ближайшую неделю допишу и выложу практическую часть. У меня есть ряд проблем, в основном с работой терминала и парсингом http но они вроде решаемы.

Спасибо! Пока.

Полезные URL


  1. В данном проекте мне очень помогла вот эта вот статья Let`s Build A Web Server
  2. Прошить ESP8266 мне помогла статья Restoring AT Firmware on the ESP8266
  3. Не стоит недооценивать силу официальной документации Примеры AT команд