diff --git a/server/src/api/health.rs b/server/src/api/health.rs index f81ed05..6ec595e 100644 --- a/server/src/api/health.rs +++ b/server/src/api/health.rs @@ -6,15 +6,16 @@ use crate::state::AppState; /// `GET /api/health` /// -/// Returns server uptime, active sessions, connected agents and version. +/// Returns server uptime, active sessions, connected agents, connected viewers, and version. pub async fn health(state: web::Data>) -> HttpResponse { let uptime = state.started_at.elapsed().as_secs(); - let (sessions, agents) = state.stats(); + let (active_sessions, connected_agents, connected_viewers) = state.stats(); let info = HealthInfo { status: "ok".into(), uptime_secs: uptime, - active_sessions: sessions, - connected_agents: agents, + active_sessions, + connected_agents, + connected_viewers, version: env!("CARGO_PKG_VERSION").into(), }; HttpResponse::Ok().json(ApiResponse::ok(info)) diff --git a/server/src/api/sessions.rs b/server/src/api/sessions.rs index a69a621..275daa2 100644 --- a/server/src/api/sessions.rs +++ b/server/src/api/sessions.rs @@ -2,7 +2,7 @@ use actix_web::{web, HttpResponse}; use serde::Deserialize; use std::sync::Arc; -use crate::models::{ApiResponse, Session}; +use crate::models::{ApiResponse, Session, WsMessage}; use crate::state::AppState; /// `GET /api/sessions` — list every session. @@ -54,8 +54,8 @@ pub struct HudCommandPayload { /// `POST /api/sessions/{id}/hud` — send a HUD command to the agent for a session. /// -/// The command is forwarded to the connected agent via the session's agent -/// channel (stored in AppState). If no agent is connected, returns 409. +/// Forwards the command through the agent's mpsc channel so it reaches the +/// agent's WebSocket connection in real time. pub async fn send_hud_command( state: web::Data>, path: web::Path, @@ -63,26 +63,24 @@ pub async fn send_hud_command( ) -> HttpResponse { let session_id = path.into_inner(); - // Find the first agent registered for this session. - let agent_id = state - .agents - .iter() - .find(|r| r.session_id == session_id) - .map(|r| r.agent_id.clone()); - - match agent_id { - Some(aid) => { - // TODO: in the WS handler we will add a per-agent mpsc sender so - // we can forward the HUD command there. For now log and acknowledge. - log::info!( - "HUD command '{}' for session {} → agent {} (params: {})", - body.command, - session_id, - aid, - body.params - ); - HttpResponse::Ok().json(ApiResponse::ok("command forwarded")) + // Build the forward message. + let msg = WsMessage::ForwardHudCommand { + command: body.command.clone(), + params: body.params.clone(), + }; + let json = match serde_json::to_string(&msg) { + Ok(j) => j, + Err(e) => { + return HttpResponse::InternalServerError() + .json(ApiResponse::<()>::err(format!("serialization error: {}", e))); } - None => HttpResponse::Conflict().json(ApiResponse::<()>::err("no agent connected for this session")), + }; + + // Send through the agent channel. + if state.send_to_agent(&session_id, &json).await { + HttpResponse::Ok().json(ApiResponse::ok("command forwarded")) + } else { + HttpResponse::Conflict() + .json(ApiResponse::<()>::err("no agent connected for this session")) } } diff --git a/server/src/models.rs b/server/src/models.rs index 95705c0..594f8a4 100644 --- a/server/src/models.rs +++ b/server/src/models.rs @@ -141,5 +141,6 @@ pub struct HealthInfo { pub uptime_secs: u64, pub active_sessions: usize, pub connected_agents: usize, + pub connected_viewers: usize, pub version: String, }