test voice rooms

This commit is contained in:
2026-01-02 15:32:59 +05:00
parent 16b477045c
commit baa4341129
3 changed files with 71 additions and 3 deletions

39
app/api/voice_ws.py Normal file
View File

@ -0,0 +1,39 @@
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query
from app.realtime.voice_hub import voice_hub
router = APIRouter()
@router.websocket("/ws/voice")
async def voice_ws(
ws: WebSocket,
room_id: str = Query(...),
username: str = Query(...)
):
await voice_hub.connect(room_id, username, ws)
# уведомим остальных
await voice_hub.broadcast(
room_id,
{"type": "join", "user": username}
)
try:
while True:
msg = await ws.receive_json()
if msg["type"] == "signal":
await voice_hub.send_to(
room_id,
msg["to"],
{
"type": "signal",
"from": username,
"data": msg["data"]
}
)
except WebSocketDisconnect:
voice_hub.disconnect(room_id, username)
await voice_hub.broadcast(
room_id,
{"type": "leave", "user": username}
)

30
app/realtime/voice_hub.py Normal file
View File

@ -0,0 +1,30 @@
from typing import Dict
from fastapi import WebSocket
class VoiceHub:
def __init__(self):
# room_id -> username -> websocket
self.rooms: Dict[str, Dict[str, WebSocket]] = {}
async def connect(self, room_id: str, username: str, ws: WebSocket):
await ws.accept()
self.rooms.setdefault(room_id, {})[username] = ws
def disconnect(self, room_id: str, username: str):
room = self.rooms.get(room_id)
if not room:
return
room.pop(username, None)
if not room:
self.rooms.pop(room_id, None)
async def send_to(self, room_id: str, to_user: str, payload: dict):
ws = self.rooms.get(room_id, {}).get(to_user)
if ws:
await ws.send_json(payload)
async def broadcast(self, room_id: str, payload: dict):
for ws in self.rooms.get(room_id, {}).values():
await ws.send_json(payload)
voice_hub = VoiceHub()