Initial commit
This commit is contained in:
76
hsbg_ai/backend/api/routes/websocket_routes.py
Normal file
76
hsbg_ai/backend/api/routes/websocket_routes.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user