Эхо-сервер на Python (websockets)

Тот же эхо-сервер, но на Python с библиотекой websockets и asyncio.

websockets — асинхронная библиотека Python для WebSocket-серверов и клиентов, построенная на asyncio.

Та же идея на другом языке

Логика не меняется: принять подключение, на каждое сообщение ответить эхом. Меняется лишь синтаксис — Python использует async/await. Код серверный, исполняется под Python, не в браузере — для чтения:

# server.py — запускается: python server.py
import asyncio
import websockets

async def echo(websocket):
    print("Клиент подключился")
    async for message in websocket:
        print("Получено:", message)
        await websocket.send("эхо: " + message)

async def main():
    async with websockets.serve(echo, "localhost", 8080):
        print("Сервер слушает ws://localhost:8080")
        await asyncio.Future()  # работать вечно

asyncio.run(main())

Что здесь происходит

  • websockets.serve(echo, ...) — поднимает сервер, на каждое подключение вызывает echo.
  • async for message in websocket — асинхронный цикл по входящим сообщениям; ждёт, пока придёт следующее.
  • await websocket.send(...) — отправка обратно.
  • await asyncio.Future() — приём, чтобы сервер не завершился.

Node против Python — где что

ПризнакNode (ws)Python (websockets)
Стильколбэки/событияasync/await
Новое сообщениеsocket.on("message")async for message
Отправкаsocket.send()await websocket.send()

Как работает под капотом

И ws, и websockets делают одно и то же по протоколу: перехватывают Upgrade, отвечают 101, разбирают фреймы. Разница — в модели конкурентности. Node изначально однопоточный и событийный, Python websockets опирается на asyncio: тысячи соединений обслуживаются в одном цикле событий за счёт await на ожидании сети, без потока на каждого клиента.

Частые ошибки

  • Забыть await перед send. Без него корутина не выполнится, сообщение не уйдёт.
  • Блокировать цикл событий. Тяжёлые синхронные вычисления в обработчике застопорят все соединения — выносите их в отдельный поток/процесс.
  • Путать версии API. Сигнатура обработчика в разных версиях websockets отличалась; сверяйтесь с документацией своей версии.

Итоги

  • На Python эхо-сервер пишут на библиотеке websockets поверх asyncio.
  • Входящие читают через async for message in websocket, шлют через await websocket.send.
  • Протокол тот же, что и у Node; различается лишь стиль (async/await против колбэков).
  • Не блокируйте цикл событий тяжёлыми синхронными операциями.
Проверьте себя
1. Как в библиотеке websockets читают входящие сообщения?
Asocket.on('message')
Basync for message in websocket
Cwebsocket.recv_all()
Dwhile True: socket.read()
2. Почему перед websocket.send в Python нужен await?
AЭто синтаксическое украшение
Bsend — корутина; без await отправка не выполнится
Cawait шифрует данные
DБез await упадёт браузер