api: wire up real agent channel for HUD commands, add connected_viewers to health
This commit is contained in:
parent
2344060d73
commit
4bc5e099cc
@ -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<Arc<AppState>>) -> 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))
|
||||
|
||||
@ -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<Arc<AppState>>,
|
||||
path: web::Path<String>,
|
||||
@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user