Files
hsbg-ai/hsbg_ai/backend/api/routes/websocket_routes.py
2026-03-31 13:10:46 +02:00

77 lines
2.7 KiB
Python

"""Routes WebSocket — Mises à jour en temps réel."""
import asyncio
import json
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Request
import structlog
router = APIRouter()
log = structlog.get_logger()
_clients: list[WebSocket] = []
@router.websocket("/game")
async def ws_game(websocket: WebSocket, request: Request):
"""WebSocket principal pour conseils en temps réel."""
await websocket.accept()
_clients.append(websocket)
log.info("ws.client_connected", total=len(_clients))
try:
while True:
raw = await websocket.receive_text()
msg = json.loads(raw)
msg_type = msg.get("type")
if msg_type == "state_update":
# L'état du jeu a changé → calculer un conseil
ai = request.app.state.ai_service
if ai:
advice = await ai.get_advice(msg.get("state", {}))
await websocket.send_json({
"type": "advice",
"data": {
"action": advice.main_decision.action,
"reasoning": advice.main_decision.reasoning,
"confidence": advice.main_decision.confidence,
"warnings": advice.main_decision.warnings,
"board_analysis": advice.board_analysis,
"model": advice.model_used,
"ms": advice.processing_ms,
}
})
elif msg_type == "ping":
await websocket.send_json({"type": "pong", "ts": asyncio.get_event_loop().time()})
elif msg_type == "screenshot_request":
# Demande de capture d'écran
vis = request.app.state.vision_service
if vis:
state = await vis.capture_now()
await websocket.send_json({
"type": "screenshot_result",
"state": state,
"screenshot": vis.get_screenshot_b64(),
})
except WebSocketDisconnect:
_clients.remove(websocket)
log.info("ws.client_disconnected", total=len(_clients))
except Exception as e:
log.error("ws.error", error=str(e))
if websocket in _clients:
_clients.remove(websocket)
async def broadcast(message: dict):
"""Diffuse un message à tous les clients connectés."""
disconnected = []
for client in _clients:
try:
await client.send_json(message)
except Exception:
disconnected.append(client)
for c in disconnected:
_clients.remove(c)