И создавать приложения в реальном времени.

Протокол передачи гипертекста (или HTTP) - один из наиболее часто используемых протоколов в Интернете сегодня. Он позволяет клиенту получать ресурсы, такие как HTML-страницы и изображения. Эта статья, которую вы сейчас читаете, была передана через HTTP (на самом деле, его защищенная форма, HTTPS).

Клиент (обычно браузер) запрашивает ресурс (изображение, файл CSS и т. Д.) На сервере, и сервер отвечает запрошенными данными. Это строго однонаправленный протокол. Сервер будет отправлять данные только по запросу клиента.

Откройте соединение, запросите то, что вы хотите, дождитесь ответа и закройте соединение. Это основа HTTP. Он отлично работает, когда вы работаете с документами. Но когда дело доходит до приложений «реального времени», таких как игры и чаты, у вас возникают некоторые проблемы с этим подходом.

Поскольку сервер не может отправить клиенту сообщение при изменении ресурса, клиенту придется постоянно запрашивать у сервера данные ресурса. Это тратит ресурсы, так как новое соединение создается для всего запроса, даже если ничего не изменилось. Этот метод называется опросом, и хотя есть некоторые методы его минимизации (например, длинный опрос), они всего лишь обходные пути к проблеме.

WebSocket

Вот где родилась идея WebSocket. Это позволяет поддерживать соединение TCP, поэтому и сервер, и клиент могут отправлять данные друг другу без необходимости каждый раз создавать новое соединение.

Он использует HTTP в качестве начального транспортного механизма, но «обновляет» соединение. Затем создается двунаправленный полнодуплексный канал связи.

Примечание: если вы хотите узнать больше о протоколе Websocket, ознакомьтесь с этой статьей.

FastAPI

FastAPI - очень крутой фреймворк с открытым исходным кодом для создания API с использованием Python. Его синтаксис похож на Flask, поэтому, если вы его используете, у вас не должно возникнуть проблем с его изучением.

У него есть некоторые преимущества перед Flask, такие как:

  • Это быстро (по сравнению с Flask);
  • Имеет автоматические документы (OpenAPI);
  • Он может использовать функции async;
  • Имеет поддержку websocket;
  • И многое другое;

Это относительно новая разработка (‹2 года), но уже набрала 27 тысяч звезд на Github .

Пример

В этом руководстве мы собираемся создать простое приложение, которое обновляет диаграмму с помощью соединения WebSocket.

Пакеты, которые мы собираемся использовать:

  • FastAPI, версия 0.63.0, для бэкэнда.
  • ReactJS, версия 17.0.1, для фронтенда.
  • Recharts, версия 2.0.6, для создания красивых графиков.

TL; DR: полный код вы можете найти в этом Github.

Сервер

Первое, что нам нужно сделать, это создать наш бэкэнд. Для этого создайте папку с именем backend. Сюда мы собираемся поместить все наши файлы.

$ mkdir backend
$ cd backend

Создайте virtualenv и установите пакет FastAPI:

$ virtualenv websocket
$ source ./websocket/bin/activate
(websocket) $ pip install fastapi "uvicorn[standard]"

Примечание: пакет uvicorn необходим для создания сервера ASGI для нашего приложения.

Создайте файл с именем run.py и поместите следующий контент:

Функция должна быть украшена функцией app.websocket, чтобы приложение FastAPI знало, что это HTTP-соединение должно быть обновлено до WebSocket. Это достигается функцией websocket.accept.

После этого мы создаем цикл для непрерывного приема и отправки данных клиенту. Если мы не выполняем цикл, мы автоматически закрываем соединение (и это будет обычное HTTP-соединение).

Для запуска сервера достаточно выполнить команду:

(websocket)$ uvicorn run:app

Клиент

Мы собираемся использовать React для создания простого клиента, который будет использовать этот веб-сервер и обновлять диаграмму каждый раз при получении новых данных.

Сначала давайте создадим новое приложение с create-react-app. Это установит все необходимые зависимости и конфигурацию:

$ yarn create react-app websocket
$ cd websocket

И установите зависимость Recharts:

$ yarn add recharts

Для подключения к нашему серверу мы будем использовать WebSocket API. Чтобы создать новый объект, нам просто нужно сообщить URL-адресу, что наш сервер прослушивает соединение WebSocket:

const ws = new WebSocket('ws://localhost:8000/ws');

Чтобы не делать этого каждый раз, мы поместили это в метод componentDidMount.

Мы также устанавливаем интервал, при котором каждую секунду на сервер будет отправляться эхо-сообщение, чтобы поддерживать соединение.

Объект websocket содержит метод onmessage, который будет вызываться каждый раз при получении нового сообщения. Затем мы устанавливаем состояние компонента с новым значением, обновляя диаграмму.

Примечание: чтобы диаграмма не оставалась большой, мы удаляем старые данные, как только будет достигнут предел.

Вот и все. Полный код компонента будет примерно таким:

Теперь просто запустите клиент с yarn start и откройте браузер по URL-адресу localhost:3000. Должна появиться диаграмма, и данные будут автоматически обновлены на вашем экране.

Заключение

Протокол HTTP ограничен, когда нам нужно создать приложение реального времени, поскольку соединение закрывается при каждом запросе.

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

В этом руководстве мы увидели, как настроить сервер WebSocket с помощью библиотеки FastAPI и использовать его с помощью React.

Полный код находится здесь.