Expand description
browser and native signaling protocol for o-sfu
o-sfu-protocol keeps client-side protocol state pure
the core state machine accepts host events and returns ordered command
vectors that the embedding host executes through its own WebSocket,
RTCPeerConnection and timer APIs
the crate has 3 public facades:
hostis the state-machine surface for browser, native and test hostswirecontains JSON envelope and signaling payload typesbundlepreserves the browser bundle compatibility API used by Odoo
Hosts execute every command in each returned vector before reporting the
resulting socket and peer-connection events to the same
host::ProtocolCore. The host creates the peer connection when applying
an initial offer. While that negotiation is pending, the host
submits its correlated answer then reports readiness after the peer
connection becomes usable.
use o_sfu_protocol::host::{Command, ConnectionState, NegotiationKind, ProtocolCore};
let mut core = ProtocolCore::new();
let connect = core.connect("wss://sfu.test/ws", "signed-token", None);
assert!(matches!(
connect.as_slice(),
[
Command::SetAvailableFeatures { .. },
Command::SetRecordingState { .. },
Command::EmitStateChange { state: ConnectionState::Connecting, .. },
Command::Connect { .. },
]
));
let auth = core.on_ws_open();
assert!(matches!(auth.as_slice(), [Command::SendWebSocket { .. }]));
let welcome = core.on_ws_message(welcome);
assert!(matches!(welcome.get(2),
Some(Command::EmitStateChange { state: ConnectionState::Authenticated, .. })
));
let offer = r#"[{"t":"offer","q":"offer-1","p":{"sdp":"v=0\r\n","uploadSlots":[]}}]"#;
let negotiation = core.on_ws_message(offer);
let [Command::ApplyNegotiation { request_id, kind, .. }] = negotiation.as_slice()
else {
return Err("unexpected negotiation command order".into());
};
assert!(core.on_transport_ready().is_empty());
let answer = core.submit_negotiation_answer(request_id, *kind, "v=0\r\ns=answer\r\n");
assert_eq!(*kind, NegotiationKind::Offer);
assert!(matches!(answer.as_slice(), [Command::SendWebSocket { .. }]));
// The host sends `answer` then waits until the peer connection is usable.
let ready = core.on_transport_ready();
assert_eq!(
ready.as_slice(),
&[Command::EmitStateChange { state: ConnectionState::Connected, cause: None }]
);Modulesยง
- bundle
- browser bundle compatibility API
- bundle_
api ๐ - rust payloads for odoo browser bundle state and updates
- core ๐
- Pure client-side signaling state machine for the
o-sfuprotocol. - host
- host-owned protocol state machine and side-effect commands
- host_
bridge ๐ - shared ๐
- signaling ๐
- Native signaling protocol surface and wire codec.
- wire
- JSON wire envelopes and signaling payloads