diff --git a/CONTEXT.md b/CONTEXT.md index 3b9d002..93419bd 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -40,7 +40,10 @@ assembly is created (see issue #36). - **Host** exposes **MediaDevices** as the API entry point for capture access. - A **Caller** sends an SDP offer and a **Callee** returns an SDP answer. -## Flagged ambiguities +## Notes -- "Host" previously meant the signaling initiator peer; resolved to the API root - object. Signaling roles are now **Caller** and **Callee**. +- **Host** is a static API entry point (like Navigator in browsers), not a signaling + role. Do not confuse with **Caller** and **Callee**, which are peer roles. +- **Caller** and **Callee** roles are bound to TCP roles: Caller is the TCP client + (connects first, sends offer); Callee is the TCP server (listens first, answers + offer). This alignment is documented in ADR-0002. diff --git a/docs/adr/0002-caller-callee-tcp-alignment.md b/docs/adr/0002-caller-callee-tcp-alignment.md new file mode 100644 index 0000000..f30a1ce --- /dev/null +++ b/docs/adr/0002-caller-callee-tcp-alignment.md @@ -0,0 +1,5 @@ +# Caller and Callee roles align with TCP connection roles + +WebRTC roles (Caller/Callee, defined by offer/answer semantics) will be bound to transport roles (TCP client/server) to avoid confusion in the BasicVideoChat example. The Caller initiates the TCP connection (acts as client) and sends the offer; the Callee listens for the TCP connection (acts as server) and responds with an answer. + +We rejected decoupling transport and WebRTC roles because it adds cognitive load without benefit — a single peer cannot simultaneously listen (server) while also creating the offer (Caller) in a direct peer-to-peer TCP model. Binding them simplifies the example and documentation, making it clear to new readers that roles are stable and consistent throughout the session. diff --git a/examples/BasicVideoChat/MainWindow.xaml.cs b/examples/BasicVideoChat/MainWindow.xaml.cs index 82bcf43..35fa6a6 100644 --- a/examples/BasicVideoChat/MainWindow.xaml.cs +++ b/examples/BasicVideoChat/MainWindow.xaml.cs @@ -35,10 +35,10 @@ public MainWindow() private bool IsCaller => CallerRadio.IsChecked == true; private void CallerRadio_Checked(object sender, RoutedEventArgs e) => - IpBox.IsEnabled = false; + IpBox.IsEnabled = true; private void CalleeRadio_Checked(object sender, RoutedEventArgs e) => - IpBox.IsEnabled = true; + IpBox.IsEnabled = false; private async void ConnectBtn_Click(object sender, RoutedEventArgs e) { @@ -102,10 +102,11 @@ private async Task StartCallAsync() if (IsCaller) { + var callerIp = IpBox.Text.Trim(); var port = int.TryParse(PortBox.Text, out var p) ? p : DefaultPort; - SetStatus($"Listening on port {port}..."); - await _signaling.ListenAsync(port); - SetStatus("Callee connected. Creating offer..."); + SetStatus($"Connecting to {callerIp}:{port}..."); + await _signaling.ConnectAsync(callerIp, port); + SetStatus("Connected. Creating offer..."); // Drive the offer explicitly here rather than relying on OnNegotiationNeeded, // since we control when the signaling channel is ready. @@ -116,11 +117,10 @@ private async Task StartCallAsync() } else { - var callerIp = IpBox.Text.Trim(); var port = int.TryParse(PortBox.Text, out var p) ? p : DefaultPort; - SetStatus($"Connecting to {callerIp}:{port}..."); - await _signaling.ConnectAsync(callerIp, port); - SetStatus("Connected. Waiting for offer..."); + SetStatus($"Listening on port {port}..."); + await _signaling.ListenAsync(port); + SetStatus("Caller connected. Waiting for offer..."); } } diff --git a/examples/BasicVideoChat/Signaling/TcpSignalingChannel.cs b/examples/BasicVideoChat/Signaling/TcpSignalingChannel.cs index 7f3ecb8..a38d448 100644 --- a/examples/BasicVideoChat/Signaling/TcpSignalingChannel.cs +++ b/examples/BasicVideoChat/Signaling/TcpSignalingChannel.cs @@ -13,8 +13,8 @@ namespace BasicVideoChat.Signaling; /// Minimal TCP signaling channel for peer-to-peer connection setup. /// /// -/// One peer calls (Host) and the other calls -/// (Guest). Messages are newline-delimited JSON. +/// The Caller calls (TCP client) and the Callee calls +/// (TCP server). Messages are newline-delimited JSON. /// /// The read loop awaits before processing the next message, /// ensuring that SetRemoteDescription always completes before any