test voice rooms
This commit is contained in:
39
app/api/voice_ws.py
Normal file
39
app/api/voice_ws.py
Normal 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
30
app/realtime/voice_hub.py
Normal 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()
|
||||||
5
main.py
5
main.py
@ -3,14 +3,12 @@ import os
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
import httpx
|
import httpx
|
||||||
from app.api import admin_daily_quests, inventory, news, users, skins, capes, meta, server, store, pranks, marketplace, bonuses, case, promo
|
from app.api import admin_daily_quests, inventory, news, users, skins, capes, meta, server, store, pranks, marketplace, marketplace_ws, bonuses, case, promo, voice_ws
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
from app.core.config import CAPES_DIR, CAPES_STORE_DIR, SKINS_DIR
|
from app.core.config import CAPES_DIR, CAPES_STORE_DIR, SKINS_DIR
|
||||||
from app.services.promo import PromoService
|
from app.services.promo import PromoService
|
||||||
from app.webhooks import telegram
|
from app.webhooks import telegram
|
||||||
from app.db.database import users_collection
|
|
||||||
from app.api import marketplace_ws
|
|
||||||
from app.db.database import users_collection, sessions_collection
|
from app.db.database import users_collection, sessions_collection
|
||||||
|
|
||||||
|
|
||||||
@ -75,6 +73,7 @@ app.include_router(news.router)
|
|||||||
app.include_router(telegram.router)
|
app.include_router(telegram.router)
|
||||||
app.include_router(admin_daily_quests.router)
|
app.include_router(admin_daily_quests.router)
|
||||||
app.include_router(promo.router)
|
app.include_router(promo.router)
|
||||||
|
app.include_router(voice_ws.router)
|
||||||
|
|
||||||
# Монтируем статику
|
# Монтируем статику
|
||||||
app.mount("/skins", StaticFiles(directory=str(SKINS_DIR)), name="skins")
|
app.mount("/skins", StaticFiles(directory=str(SKINS_DIR)), name="skins")
|
||||||
|
|||||||
Reference in New Issue
Block a user