[fix](trx-frontend-http): filter SSE channel events by rig and fix audio hang

Channel SSE events were broadcast to all tabs regardless of rig, causing tabs to display wrong rig's channels. Per-rig audio info_rx override caused WebSocket to hang waiting for stream info that never arrives.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-03-22 07:17:26 +01:00
parent 9900314c8c
commit bf754f573a
2 changed files with 31 additions and 26 deletions
@@ -473,13 +473,24 @@ pub async fn events(
});
// Channel-list change events from the virtual channel manager.
// Only forward events for this SSE session's rig so tabs viewing
// different rigs don't see each other's channel lists.
let vchan_change_rx = vchan_mgr.change_tx.subscribe();
let chan_updates = futures_util::stream::unfold(vchan_change_rx, |mut rx| async move {
let session_rig_for_chan = active_rig_id.clone();
let chan_updates = futures_util::stream::unfold(
(vchan_change_rx, session_rig_for_chan),
|(mut rx, srig)| async move {
loop {
match rx.recv().await {
Ok(msg) => {
if let Some(colon) = msg.find(':') {
let rig_id = &msg[..colon];
// Skip channel events that belong to a different rig.
if let Some(ref expected) = srig {
if rig_id != expected.as_str() {
continue;
}
}
let channels_json = &msg[colon + 1..];
let payload =
format!("{{\"rig_id\":\"{rig_id}\",\"channels\":{channels_json}}}");
@@ -487,7 +498,7 @@ pub async fn events(
Ok::<Bytes, Error>(Bytes::from(format!(
"event: channels\ndata: {payload}\n\n"
))),
rx,
(rx, srig),
));
}
}
@@ -495,7 +506,8 @@ pub async fn events(
Err(broadcast::error::RecvError::Closed) => return None,
}
}
});
},
);
// Send a named "ping" event so the JS heartbeat can observe it.
let pings = IntervalStream::new(time::interval(Duration::from_secs(5)))
@@ -537,13 +537,6 @@ pub async fn audio_ws(
};
let mut rx_sub = rx_sub;
// Use per-rig audio info if available and rig_id was specified.
if let Some(ref rig_id) = query.rig_id {
if let Some(rig_info_rx) = context.rig_audio_info_rx(rig_id) {
info_rx = rig_info_rx;
}
}
let (response, mut session, mut msg_stream) = actix_ws::handle(&req, body)?;
actix_web::rt::spawn(async move {