Гайды
WebSockets: чат на FastAPI
Минимальный эндпоинт, комната в памяти, аутентификация, JSON-протокол, heartbeat и мульти-инстанс.
~10 мин чтения
WebSockets: чат на FastAPI
WebSocket — полнодуплексный канал поверх HTTP с upgrade; сервер и клиент шлют фреймы без оверхеда нового HTTP-запроса на каждое сообщение. В FastAPI — WebSocket из Starlette. База фреймворка — Быстрый старт с FastAPI; asyncio — asyncio в Python; прокси — Деплой FastAPI: Docker и Nginx.
1. Минимальный эндпоинт
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
app = FastAPI()
@app.websocket("/ws")
async def ws_endpoint(ws: WebSocket):
await ws.accept()
try:
while True:
data = await ws.receive_text()
await ws.send_text(f"echo: {data}")
except WebSocketDisconnect:
pass
2. Чат-комната (память процесса)
class Room:
def __init__(self):
self.clients: set[WebSocket] = set()
async def connect(self, ws: WebSocket):
await ws.accept()
self.clients.add(ws)
def disconnect(self, ws: WebSocket):
self.clients.discard(ws)
async def broadcast(self, message: str):
for c in list(self.clients):
await c.send_text(message)
rooms: dict[str, Room] = {}
@app.websocket("/chat/{room_id}")
async def chat(ws: WebSocket, room_id: str):
room = rooms.setdefault(room_id, Room())
await room.connect(ws)
try:
while True:
msg = await ws.receive_text()
await room.broadcast(msg)
except WebSocketDisconnect:
room.disconnect(ws)
Для нескольких инстансов приложения нужен pub/sub — Redis Pub/Sub и очереди, NATS.
3. Аутентификация
- Токен в query:
wss://api/ws?token=...(осторожно с логами). - Или cookie + same-site политика.
- После
accept()можно отклонить, отправивcloseи вернув из хендлера.
4. Протокол сообщений
Используйте JSON с полем type (join, message, error) для совместимости клиентов.
5. Heartbeat
Прокси и балансировщики рвут «тихие» соединения. Периодически шлите ping (Starlette умеет автоматический ping/pong WebSocket) или прикладной keep-alive.
6. Масштаб и backpressure
Не накапливайте неограниченную очередь исходящих сообщений; при перегрузке — close с кодом.
7. Чек-лист
-
wss://в проде. - Nginx
proxy_read_timeoutдостаточен. - Мульти-инстанс — общий брокер для broadcast.
- Валидация входящих JSON (размер, схема).
Дальше: WebRTC · тег FastAPI