
How WebRTC Works
The typical workflow of WebRTC includes the following steps:
- Media capture: Use the MediaStream API to capture audio and video.
- Signaling: WebRTC does not specify a signaling protocol; developers must implement their own signaling mechanism (commonly via WebSocket or REST APIs) to exchange metadata such as SDP descriptors and ICE candidates. The signaling server is responsible for peer discovery, room management, and forwarding media and network information.
- Connection establishment: Establish a peer-to-peer connection via RTCPeerConnection.
- Media negotiation: Exchange audio/video codec capabilities via SDP to ensure both sides can encode and decode correctly.
- NAT traversal: Use the ICE framework; discover public addresses via a STUN server. If direct connectivity fails, route traffic through a TURN server to handle different NAT types. ICE candidates have priorities, including host candidates (local LAN IP), server reflexive candidates (public IP behind NAT), and relay candidates (TURN server addresses).
- Data exchange: RTCDataChannel allows peers to exchange data over the established connection.
Flowchart: End-to-End Connection Establishment Overview
flowchart LR
A[Local Browser\ngetUserMedia captures media] --> B[Signaling Channel\nvia WebSocket or HTTP]
A --> C[Create RTCPeerConnection]
C --> D[Create SDP Offer]
D -->|Send via signaling| E[Remote Browser]
E --> F[Set remote SDP\nand create Answer]
F -->|Return via signaling| C
C --> G[ICE Candidate Gathering\nincluding STUN queries]
G -->|Send candidates| E
E -->|Return candidates| C
C --> H{Direct connection?}
H -->|Yes| I[Establish P2P direct link\nMedia and data direct]
H -->|No| J[Relay via TURN\nEstablish connection]
I --> K[Media Streams and Data Channels\nStable transfer]
J --> K
The flowchart above outlines the key steps from local media capture and SDP negotiation to ICE/STUN/TURN selection and final media/data transmission.
Sequence Diagram: SDP/ICE Signaling Exchange
sequenceDiagram
%% Detailed SDP/ICE sequence
participant L as Local Browser
participant S as Signaling Server
participant R as Remote Browser
Note over L: getUserMedia() acquires audio/video tracks
L->>L: new RTCPeerConnection()
L->>L: addTrack()/addTransceiver()
L->>L: createOffer() / setLocalDescription(offer)
L->>S: Send SDP Offer
S->>R: Forward SDP Offer
R->>R: setRemoteDescription(offer)
R->>R: createAnswer() / setLocalDescription(answer)
R->>S: Send SDP Answer
S->>L: Forward SDP Answer
L->>L: setRemoteDescription(answer)
par ICE Candidate Exchange
L->>L: Gather local ICE candidates (incl. STUN reflexive)
L->>S: Send ICE candidates
S->>R: Forward ICE candidates
R->>S: Return ICE candidates
S->>L: Forward ICE candidates
end
alt Direct connection succeeds
L-->>R: Establish P2P media/data channels
else Direct connection fails
L-->>R: Connect via TURN relay
end
The sequence diagram focuses on the exchange of SDP and ICE candidates through the signaling server, showing the key round trips needed to establish a typical call.
Plain-language notes
Signaling / SDP
- Signaling: say hello first and agree how to talk.
- SDP: list A/V capabilities; start only when both sides match.
ICE / STUN / TURN
- Prefer direct; if blocked, use STUN to discover public address; if still blocked, relay via TURN.
- Direct = lower latency; TURN = more reliable but with cost.
Media vs DataChannel
- Media streams are like live broadcast.
- DataChannel is like a walkie-talkie/parcel: either faster with possible loss, or strict, reliable, in-order.
Minimal snippet
仅演示流程;实际需要信令后端。
// 关键步骤示例(注释为中文,符合项目规范)
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
stream.getTracks().forEach(t => pc.addTrack(t, stream));
// 创建本地 SDP 并通过信令发送
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signaling.send({ type: 'offer', sdp: offer.sdp });
// 发送本地 ICE 候选
pc.onicecandidate = (e) => e.candidate && signaling.send({ type: 'candidate', candidate: e.candidate });
// 设置远端应答
signaling.on('answer', async ({ sdp }) => pc.setRemoteDescription({ type: 'answer', sdp }));
// 可选:数据通道
const dc = pc.createDataChannel('chat', { ordered: false });
dc.onopen = () => dc.send('hi');
Tags
Copyright Notice
This article is created by WebRTC.link and licensed under CC BY-NC-SA 4.0. This site repost articles will cite the source and author. If you need to repost, please cite the source and author.
Comments
GiscusComments powered by Giscus, based on GitHub Discussions