from fastapi import HTTPException, status, APIRouter, WebSocket, WebSocketDisconnect, Query from app.core.security import test_token from typing import Dict from datetime import datetime wsRouter = APIRouter( prefix="/ws", tags=[], ) @wsRouter.websocket("") async def websocket_endpoint(websocket: WebSocket, token: str = Query(None)): if token is None: await websocket.close(code=status.WS_1008_POLICY_VIOLATION) return try: user_id = await test_token(token=token) except HTTPException: await websocket.close(code=status.WS_1008_POLICY_VIOLATION) return await manager.connect(user_id, websocket) try: while True: data = await websocket.receive_json() receiver_id = str(data.get("receiver_id")) message_to_send = { "sender_id": user_id, "text": data.get("text"), "created_at": datetime.now().isoformat() } await manager.send_personal_message(message_to_send, receiver_id) await manager.send_personal_message(message_to_send, user_id) except WebSocketDisconnect: pass finally: manager.disconnect(user_id) class ConnectionManager: def __init__(self): # Храним активные соединения: {user_id: websocket} self.active_connections: Dict[str, WebSocket] = {} async def connect(self, user_id: str, websocket: WebSocket): await websocket.accept() self.active_connections[user_id] = websocket def disconnect(self, user_id: str): if user_id in self.active_connections: del self.active_connections[user_id] async def send_personal_message(self, message: dict, user_id: str): if user_id in self.active_connections: await self.active_connections[user_id].send_json(message) async def broadcast(self, message: dict): # Рассылка вообще всем (например, системное уведомление) for connection in self.active_connections.values(): await connection.send_json(message) manager = ConnectionManager()