[feat](trx-rs): persistent multi-channel virtual channels with OOB eviction
Allow users to allocate multiple virtual channels independently of browser tab count. Channels survive SDR center-frequency retuning as long as they stay within the capture bandwidth; channels that fall outside the SDR span are automatically destroyed. Changes: - trx-core: add AUDIO_MSG_VCHAN_DESTROYED (0x12) wire constant; add default subscribe_destroyed() to VirtualChannelManager trait - trx-backend-soapysdr: update_center_hz() detects OOB channels, removes them, fires destroyed_tx broadcast; add destroyed_sender() and subscribe_destroyed() override - trx-server/audio: recv_destroyed() helper avoids select! busy-loop for non-SDR backends; send AUDIO_MSG_VCHAN_DESTROYED to client when a channel is evicted server-side - trx-client/audio_client: persist active_subs across TCP reconnects, re-subscribe on reconnect; handle AUDIO_MSG_VCHAN_DESTROYED by pruning vchan_audio map and forwarding UUID via vchan_destroyed_tx - trx-frontend/lib: add vchan_destroyed broadcast field to FrontendRuntimeContext - trx-client/main: wire vchan_destroyed_tx into audio client and frontend runtime context - trx-frontend-http/vchan: remove per-session one-channel limit in allocate(); replace auto-evict in release_session_on_rig() with subscriber-count-only update; add remove_by_uuid() for server- triggered OOB destruction (skips redundant VChanAudioCmd::Remove) - trx-frontend-http/server: spawn background task that forwards vchan_destroyed broadcast to ClientChannelManager.remove_by_uuid() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -56,6 +56,9 @@ pub const AUDIO_MSG_VCHAN_MODE: u8 = 0x10;
|
||||
/// Client → server: remove a virtual channel (stops encoding and destroys the DSP pipeline).
|
||||
/// Payload: 16-byte UUID of the virtual channel on the server.
|
||||
pub const AUDIO_MSG_VCHAN_REMOVE: u8 = 0x11;
|
||||
/// Server → client: a virtual channel was destroyed server-side (e.g. went out of bandwidth).
|
||||
/// Payload: 16-byte UUID of the destroyed channel.
|
||||
pub const AUDIO_MSG_VCHAN_DESTROYED: u8 = 0x12;
|
||||
|
||||
/// Maximum payload size for normal messages (1 MB).
|
||||
const MAX_PAYLOAD_SIZE: u32 = 1_048_576;
|
||||
|
||||
@@ -117,6 +117,18 @@ pub trait VirtualChannelManager: Send + Sync {
|
||||
|
||||
/// Maximum number of channels (including the primary channel).
|
||||
fn max_channels(&self) -> usize;
|
||||
|
||||
/// Subscribe to server-side channel destruction events.
|
||||
///
|
||||
/// Returns a `broadcast::Receiver<Uuid>` that fires whenever the manager
|
||||
/// destroys a channel (e.g. because it went out of the SDR capture
|
||||
/// bandwidth). The default implementation returns an immediately-closed
|
||||
/// receiver so non-SDR backends do not need to override this.
|
||||
fn subscribe_destroyed(&self) -> broadcast::Receiver<Uuid> {
|
||||
// Drop the sender immediately; the receiver will resolve to
|
||||
// `Err(RecvError::Closed)` on first poll, signalling "no events".
|
||||
broadcast::channel::<Uuid>(1).1
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience alias used in `RigHandle`.
|
||||
|
||||
Reference in New Issue
Block a user