77 lines
2.7 KiB
Python
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)
|