Skip to main content

Client

Struct Client 

Source
pub struct Client {
    pub id: ClientId,
    /* private fields */
}
Expand description

Per-peer state machine wrapping a str0m Rtc instance.

One Client exists per connected peer in the room. The registry owns all clients and is the single entity that drives them via poll_output and handle_input.

Fields§

§id: ClientId

Process-unique identifier for this peer.

Implementations§

Source§

impl Client

Source

pub fn extra_dcs(&self) -> &[ChannelConfig]

Pre-registered DataChannels to open during SDP negotiation.

The application signalling layer (e.g. partner-edge) reads this slice and calls Rtc::open_stream for each entry. Populated via with_extra_dc, with_chat_dcs, and with_voice_dc.

Source

pub fn desired_layer(&self) -> SfuRid

This subscriber’s current desired simulcast layer.

Source

pub fn set_desired_layer(&mut self, rid: SfuRid)

Override this subscriber’s desired simulcast layer.

Takes effect on the next forwarded packet; no SDP renegotiation required.

Source

pub fn active_rids(&self) -> Vec<SfuRid>

Simulcast RIDs the peer has been observed publishing.

Built up incrementally on each received MediaData. Empty until the first video packet arrives. Callers that use this as the “available layers” input should fall back to the full ladder ([LOW, MEDIUM, HIGH]) when empty — before the first packet the full ladder is the correct assumption.

Source

pub fn delivered_media_count(&self) -> u64

Number of MediaData events forwarded to this client after layer filtering.

Source

pub fn delivered_active_speaker_count(&self) -> u64

Available on crate features test-utils only.

Number of ActiveSpeakerChanged events delivered to this client.

Only available with test-utils feature; used to verify skip-self semantics.

Source

pub fn is_alive(&self) -> bool

Whether the underlying str0m Rtc is still alive.

Source

pub fn accepts(&self, datagram: &IncomingDatagram) -> bool

Demux probe — returns true if this client owns the given datagram.

Used by the registry to route incoming UDP to the correct peer.

Source

pub fn drive_pacer(&mut self, bps: u64) -> PacerAction

Available on crate feature pacer only.

Feed a new egress BWE reading to this subscriber’s pacer.

If the action is PacerAction::ChangeLayer, desired_layer is updated in-place before returning. For GoAudioOnly / RestoreVideo, the registry should emit Propagated::AudioOnlyMode.

Only available with the pacer feature.

Source

pub fn set_max_temporal_layer(&mut self, max: u8)

Available on crate feature av1-dd only.

Set the maximum AV1 temporal layer to forward to this subscriber.

Packets with temporal_id > max are dropped at fanout. Default is u8::MAX (all layers forwarded).

Only available with the av1-dd feature.

Source

pub fn max_temporal_layer(&self) -> u8

Available on crate feature av1-dd only.

Current AV1 temporal layer cap.

Only available with the av1-dd feature.

Source

pub fn set_max_vfm_temporal_layer(&mut self, max: u8)

Available on crate feature vfm only.

Set the maximum RFC 9626 temporal layer to forward to this subscriber.

Packets with temporal_id > max are dropped at fanout. Default: u8::MAX (all layers forwarded).

Source

pub fn max_vfm_temporal_layer(&self) -> u8

Available on crate feature vfm only.

Current RFC 9626 temporal layer cap.

Source

pub fn origin(&self) -> &ClientOrigin

This client’s origin (local peer or upstream SFU relay).

Source

pub fn set_origin(&mut self, origin: ClientOrigin)

Override the client origin.

Must be called before Registry::insert. See ClientOrigin for the call-order contract.

Source

pub fn is_relay(&self) -> bool

Returns true if this client is a relay connection from another SFU edge.

Source

pub fn set_suspended(&mut self, suspended: bool)

Available on crate feature pacer only.

Set the suspended flag. Called by the registry pacer path when PacerAction::SuspendVideo / RestoreAudio fires. Only available with the pacer feature.

Source

pub fn is_suspended(&self) -> bool

Available on crate feature pacer only.

Read the suspended flag.

Source§

impl Client

Source

pub fn new(rtc: SfuRtc, metrics: Arc<SfuMetrics>) -> Self

Wrap a freshly-created SfuRtc instance.

The metrics handle is replaced by the registry’s own instance when Registry::insert is called, so all counters from all clients flow to the same Prometheus registry.

Source§

impl Client

Source

pub fn with_extra_dc(self, label: &str, id: u16, cfg: ChannelConfig) -> Self

Register an additional DataChannel to open during SDP negotiation.

The label, id, and channel cfg are stored in Client::extra_dcs. The application signalling layer reads these during offer/answer and calls Rtc::open_stream(id, str0m_channel_config) for each entry.

§Example
use oxpulse_sfu_kit::{ChannelConfig, Client, SfuRtcBuilder, SfuMetrics};
use std::sync::Arc;

let rtc = SfuRtcBuilder::new().build();
let client = Client::new(rtc, Arc::new(SfuMetrics::new_default()))
    .with_extra_dc("telemetry", 20, ChannelConfig::reliable_ordered());
Source

pub fn with_chat_dcs(self) -> Self

Register the standard OxPulse chat DataChannels (id=4 and id=5).

  • "chat-data" (id=4): reliable ordered — text messages.
  • "chat-ctrl" (id=5): unreliable, 0 retransmits — typing / presence signals.

This is a thin shim over with_extra_dc; no behaviour change relative to the pre-0.10.0 implementation.

Source

pub fn with_voice_dc(self, max_pkt_lifetime_ms: u32) -> Self

Register the Phase 8 voice DataChannel (id=6).

Uses unordered delivery with Reliability::MaxPacketLifetime { lifetime: max_pkt_lifetime_ms }. For voice control signals, 200 ms is the recommended lifetime — packets older than that are useless and should be discarded.

Source§

impl Client

Source

pub fn new_for_test() -> Self

Available on crate features test-utils only.

Build a Client for integration tests without real ICE/DTLS setup.

Identical to crate::client::test_seed::new_client but available as an associated function on Client so tests can call Client::new_for_test() without importing the internal module.

Source

pub fn dc_config_for(&self, label: &str) -> Option<&ChannelConfig>

Available on crate features test-utils only.

Look up the ChannelConfig registered under label via with_extra_dc.

Returns None if no DC with that label has been registered.

Source

pub fn dc_count(&self) -> usize

Available on crate features test-utils only.

Number of DataChannels registered via with_extra_dc (and its shims).

Source§

impl Client

Source

pub fn handle_media_data_out( &mut self, origin: ClientId, data: &SfuMediaPayload, )

Forward a SfuMediaPayload from origin out to this peer.

Applies the simulcast layer filter (drops packets not matching desired_layer) and increments Prometheus counters for forwarded packets and layer selections.

Source

pub fn handle_active_speaker_changed(&mut self, _peer_id: u64)

Available on crate feature active-speaker only.

Handle a dominant-speaker election change.

The registry skips the speaker themselves (skip-self rule), so this method is only called on other clients. In test-utils builds a counter is bumped to let tests verify skip-self semantics.

Source§

impl Client

Source

pub fn handle_keyframe_request( &mut self, req: SfuKeyframeRequest, mid_in: SfuMid, )

Handle a propagated keyframe request: pass it through to str0m’s writer if this client owns the matching incoming track.

Source§

impl Client

Source

pub fn incoming_keyframe_req_for_tests( &self, req: KeyframeRequest, ) -> Propagated

Available on crate features test-utils only.

Expose incoming_keyframe_req for integration tests.

Source§

impl Client

Source

pub fn seed_active_rid_for_tests(&mut self, rid: Rid)

Available on crate features test-utils only.

Inject an observed publisher RID without running the track_in_media path.

Production code should never call this — track_in_media owns the canonical write. Used by screenshare-like tests that need to pin active_rids to a subset of the full simulcast ladder.

Source

pub fn disconnect_for_tests(&mut self)

Available on crate features test-utils only.

Mark the underlying Rtc as disconnected so is_alive returns false.

Needed for reap_dead tests — the real disconnect path requires an ICE/DTLS pipeline that integration tests don’t set up.

Source§

impl Client

Source

pub fn handle_input(&mut self, datagram: IncomingDatagram)

Feed a demuxed UDP datagram into str0m.

Source

pub fn poll_output(&mut self) -> Propagated

Drive str0m forward one step.

Outbound UDP datagrams are appended to pending_out; the registry drains them between polls via drain_pending_out.

Source

pub fn handle_track_open(&mut self, track_in: Weak<TrackIn>)

Register that another client opened a track we should mirror to this peer.

Source

pub fn drain_pending_out( &mut self, ) -> impl Iterator<Item = OutgoingDatagram> + '_

Drain queued outbound datagrams.

The registry calls this after each poll cycle to pass bytes to the tokio socket.

Trait Implementations§

Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl UnsafeUnpin for Client

§

impl !UnwindSafe for Client

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> CryptoSafe for T
where T: Send + Sync + Debug,