WebSocket на Python: быстрый пример клиента и сервера

Соберем маленький WebSocket-пример на Python:.

Ниже — разделы про что мы сделаем, почему Python-ветка нужна отдельно и подготовка, чтобы быстро понять устройство материала, практические ограничения и типовые точки отказа.


Что мы сделаем

Соберем маленький WebSocket-пример на Python:

  • сервер принимает соединение;
  • клиент отправляет сообщение;
  • сервер возвращает ответ;
  • затем усложним пример до JSON-сообщений.

Это хороший материал для тех, кто уже видел Python и хочет понять real-time без Node.js

Почему Python-ветка нужна отдельно

В статистике есть websocket python, python websocket, websockets python, python websocket client. Это не тот же интент, что websocket js. Человек уже выбрал язык и хочет конкретный код

Для Python часто используют библиотеку websockets. В современной документации основной путь идет через asyncio, поэтому в уроке будем писать асинхронный пример

Подготовка

Создайте папку:

mkdir python-websocket-demo
cd python-websocket-demo

Создайте виртуальное окружение:

python -m venv .venv

Активируйте его

macOS/Linux:

source .venv/bin/activate
.venv\Scripts\Activate.ps1

Установите библиотеку:

pip install websockets

Echo-сервер

Создайте server.py:

import asyncio
from websockets.asyncio.server import serve

async def echo(websocket):
    async for message in websocket:
        print(f"Получено: {message}")
        await websocket.send(f"Сервер получил: {message}")

async def main():
    async with serve(echo, "localhost", 8765) as server:
        print("WebSocket сервер запущен: ws://localhost:8765")
        await server.serve_forever()

if __name__ == "__main__":
    asyncio.run(main())

Запустите:

python server.py

Терминал останется занят сервером. Это нормально

Клиент

В другом терминале, в той же папке и с активированным окружением, создайте client.py:

import asyncio
from websockets.asyncio.client import connect

async def main():
    async with connect("ws://localhost:8765") as websocket:
        await websocket.send("Привет из Python-клиента")

        response = await websocket.recv()
        print(response)

if __name__ == "__main__":
    asyncio.run(main())

Запустите:

python client.py

Ожидаемый результат:

Сервер получил: Привет из Python-клиента

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

serve поднимает WebSocket-сервер

async with serve(echo, "localhost", 8765) as server:

Функция echo вызывается для соединения:

async def echo(websocket):

Цикл читает сообщения:

async for message in websocket:

Ответ отправляется обратно:

await websocket.send(...)

На клиенте connect открывает соединение, send отправляет сообщение, recv ждет ответ

Версия с JSON

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

import asyncio
import json
from datetime import datetime
from websockets.asyncio.server import serve

async def handler(websocket):
    async for raw_message in websocket:
        data = json.loads(raw_message)

        response = {
            "type": "reply",
            "text": f"Получил событие {data.get('type')}",
            "time": datetime.now().isoformat(timespec="seconds"),
        }

        await websocket.send(json.dumps(response, ensure_ascii=False))

async def main():
    async with serve(handler, "localhost", 8765) as server:
        print("JSON WebSocket сервер: ws://localhost:8765")
        await server.serve_forever()

if __name__ == "__main__":
    asyncio.run(main())
import asyncio
import json
from websockets.asyncio.client import connect

async def main():
    async with connect("ws://localhost:8765") as websocket:
        message = {
            "type": "lead_created",
            "name": "Анна",
            "email": "anna@example.com",
        }

        await websocket.send(json.dumps(message, ensure_ascii=False))

        response = await websocket.recv()
        print(json.loads(response))

if __name__ == "__main__":
    asyncio.run(main())

Такой формат уже похож на реальные события: lead_created, order_paid, task_finished, stream_started

Как проверить соединение

Запустите сервер:

python server.py

В другом терминале:

python client.py

Если клиент зависает, проверьте:

  • сервер действительно запущен;
  • порт 8765 совпадает;
  • адрес localhost написан правильно;
  • firewall не блокирует соединение;
  • вы не запускаете два сервера на одном порту.

Что делать с браузером

Python-сервер можно проверить и из браузерного JavaScript:

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

socket.addEventListener('open', () => {
  socket.send('Привет из браузера');
});

socket.addEventListener('message', (event) => {
  console.log(event.data);
});

Но если вы открываете HTML-файл напрямую, не путайте ошибку CORS с WebSocket. У WebSocket своя handshake-логика, а ошибки часто видны в DevTools во вкладке Network

Когда Python WebSocket хорош

Python-подход удобен, если:

  • backend уже на Python;
  • нужен real-time для FastAPI, Django или aiohttp;
  • вы делаете бота, парсер, сервис уведомлений;
  • данные обрабатываются Python-кодом;
  • нужно быстро собрать внутренний инструмент.

Если весь проект на Node.js, логичнее начать с Node.js. Если проект уже в Python, не обязательно тащить Node.js только ради WebSocket

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

ModuleNotFoundError: No module named 'websockets'

Библиотека не установлена в активное окружение. Проверьте активацию .venv и выполните:

pip install websockets

address already in use

Порт занят. Остановите старый сервер или поменяйте порт:

async with serve(echo, "localhost", 8766) as server:

Клиент подключается не туда

Проверьте адрес:

ws://localhost:8765

Если сервер на другом компьютере, localhost уже не подойдет

JSON ломается на русских символах

Используйте:

json.dumps(data, ensure_ascii=False)

Ответы на эти вопросы могут быть для вас полезными

Python подходит для WebSocket?

Да. Особенно если backend уже на Python или нужны интеграции с Python-кодом. Библиотека websockets дает понятный асинхронный API

Нужно ли знать asyncio?

Для нормального Python WebSocket — желательно. Можно начать с готового примера, но дальше придется понимать async, await и event loop

Можно ли подключить браузер к Python WebSocket?

Да. Браузер использует встроенный WebSocket, а сервер может быть на Python, Node.js, Go или другом языке

Что лучше: FastAPI WebSocket или чистый websockets?

Если у вас приложение на FastAPI, берите встроенную поддержку WebSocket в FastAPI. Если нужен отдельный легкий сервер или клиент, библиотека websockets удобна сама по себе

Нужно ли хранить сообщения в базе?

Если сообщения важны — да. WebSocket доставляет событие, но сам по себе не является базой данных

Что почитать дальше по WebSockets

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

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x