You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

8.3 KiB

Веб-сокеты

Вы можете использовать веб-сокеты в FastAPI.

Установка WebSockets

Убедитесь, что виртуальная среда{.internal-link target=_blank} создана, активируйте её и установите websockets:

$ pip install websockets

---> 100%

Клиент WebSockets

Рабочее приложение

Скорее всего, в вашей реальной продуктовой системе есть фронтенд, реализованный при помощи современных фреймворков React, Vue.js или Angular.

И наверняка для взаимодействия с бекендом через веб-сокеты вы будете использовать средства фронтенда.

Также у вас может быть нативное мобильное приложение, коммуницирующее непосредственно с веб-сокетами на бекенд-сервере.

Либо вы можете сделать какой-либо другой способ взаимодействия с веб-сокетами.


Но для этого примера мы воспользуемся очень простым HTML документом с небольшими вставками JavaScript кода.

Конечно же это неоптимально, и на практике так делать не стоит.

В реальных приложениях стоит воспользоваться одним из вышеупомянутых способов.

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

{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}

Создание websocket

Создайте websocket в своем FastAPI приложении:

{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}

/// note | Технические детали

Вы также можете использовать from starlette.websockets import WebSocket.

FastAPI напрямую предоставляет тот же самый WebSocket просто для удобства. На самом деле это WebSocket из Starlette.

///

Ожидание и отправка сообщений

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

{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}

Вы можете получать и отправлять двоичные, текстовые и JSON данные.

Проверка в действии

Если ваш файл называется main.py, то запустите приложение командой:

$ fastapi dev main.py

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Откройте браузер по адресу http://127.0.0.1:8000.

Вы увидите следующую простенькую страницу:

Вы можете набирать сообщения в поле ввода и отправлять их:

И ваше FastAPI приложение с веб-сокетами ответит:

Вы можете отправлять и получать множество сообщений:

И все они будут использовать одно и то же веб-сокет соединение.

Использование Depends и не только

Вы можете импортировать из fastapi и использовать в эндпоинте вебсокета:

  • Depends
  • Security
  • Cookie
  • Header
  • Path
  • Query

Они работают так же, как и в других FastAPI эндпоинтах/операциях пути:

{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *}

/// info | Примечание

В веб-сокете вызывать HTTPException не имеет смысла. Вместо этого нужно использовать WebSocketException.

Закрывающий статус код можно использовать из valid codes defined in the specification.

///

Веб-сокеты с зависимостями: проверка в действии

Если ваш файл называется main.py, то запустите приложение командой:

$ fastapi dev main.py

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Откройте браузер по адресу http://127.0.0.1:8000.

Там вы можете задать:

  • "Item ID", используемый в пути.
  • "Token", используемый как query-параметр.

/// tip | Подсказка

Обратите внимание, что query-параметр token будет обработан в зависимости.

///

Теперь вы можете подключиться к веб-сокету и начинать отправку и получение сообщений:

Обработка отключений и работа с несколькими клиентами

Если веб-сокет соединение закрыто, то await websocket.receive_text() вызовет исключение WebSocketDisconnect, которое можно поймать и обработать как в этом примере:

{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}

Чтобы воспроизвести пример:

  • Откройте приложение в нескольких вкладках браузера.
  • Отправьте из них сообщения.
  • Затем закройте одну из вкладок.

Это вызовет исключение WebSocketDisconnect, и все остальные клиенты получат следующее сообщение:

Client #1596980209979 left the chat

/// tip | Примечание

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

Но имейте в виду, что это будет работать только в одном процессе и только пока он активен, так как всё обрабатывается в простом списке в оперативной памяти.

Если нужно что-то легко интегрируемое с FastAPI, но более надежное и с поддержкой Redis, PostgreSQL или другого, то можно воспользоваться encode/broadcaster.

///

Дополнительная информация

Для более глубокого изучения темы воспользуйтесь документацией Starlette: