Back to Blog
Technology15 min read

WebRTC API Complete Technical Guide: From Interfaces to Implementation

A comprehensive deep-dive into WebRTC API architecture, core interfaces, protocol stack, and security mechanisms based on official MDN documentation.

WebRTC API Complete Technical Guide: From Interfaces to Implementation


Introduction

WebRTC (Web Real-Time Communication) is a powerful technology that enables web applications to exchange audio, video, and arbitrary data directly between browsers without intermediaries. This guide provides a comprehensive technical overview based on the official MDN Web Docs specification.

Core Architecture

WebRTC is built on a layered architecture that handles everything from network traversal to media encoding:

┌─────────────────────────────────────────────┐
│ Application Layer │
│ (Your JavaScript Application) │
├─────────────────────────────────────────────┤
│ WebRTC API Layer │
│ RTCPeerConnection RTCDataChannel etc. │
├─────────────────────────────────────────────┤
│ Session Layer │
│ SDP DTLSSCTP SRTP │
├─────────────────────────────────────────────┤
│ Network Layer │
│ ICE STUN TURN │
├─────────────────────────────────────────────┤
│ Transport Layer │
│ UDP / TCP │
└─────────────────────────────────────────────┘

Core Interfaces

RTCPeerConnection

The most important interface in WebRTC, RTCPeerConnection represents a connection between the local device and a remote peer.

const configuration = {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{
urls: 'turn:turn.example.com:3478',
username: 'user',
credential: 'password'
}
]
};

const peerConnection = new RTCPeerConnection(configuration);

Key Responsibilities:

  • Managing the connection lifecycle
  • Handling ICE candidate gathering and exchange
  • Managing media tracks (audio/video)
  • Creating and managing data channels
  • Generating and processing SDP offers/answers
  • RTCDataChannel

    Enables bidirectional transfer of arbitrary data between peers. This is the interface ZeroSend uses for file transfer.

    // Creating a data channel
    const dataChannel = peerConnection.createDataChannel('fileTransfer', {
    ordered: true, // Guarantee message order
    maxRetransmits: 3 // Maximum retry attempts
    });

    // Receiving a data channel
    peerConnection.ondatachannel = (event) => {
    const receivedChannel = event.channel;
    receivedChannel.onmessage = (e) => {
    console.log('Received:', e.data);
    };
    };

    Data Channel Options:

    OptionTypeDescription





    orderedbooleanWhether messages arrive in order
    maxPacketLifeTimenumberMax time to attempt delivery (ms)
    maxRetransmitsnumberMax number of retransmission attempts
    protocolstringSub-protocol name
    negotiatedbooleanWhether channel is negotiated out-of-band
    idnumberChannel ID (if negotiated)

    RTCSessionDescription

    Contains information about the session, particularly the SDP (Session Description Protocol) data.

    // Creating an offer
    const offer = await peerConnection.createOffer();
    await peerConnection.setLocalDescription(offer);

    // The offer contains SDP like:
    // v=0
    // o=- 4611731400430051336 2 IN IP4 127.0.0.1
    // s=-
    // t=0 0
    // a=group:BUNDLE 0
    // a=msid-semantic: WMS
    // m=application 9 UDP/DTLS/SCTP webrtc-datachannel
    // ...

    RTCIceCandidate

    Represents a candidate Interactive Connectivity Establishment (ICE) server for establishing the peer connection.

    peerConnection.onicecandidate = (event) => {
    if (event.candidate) {
    // Send this candidate to the remote peer via signaling
    signalingChannel.send({
    type: 'ice-candidate',
    candidate: event.candidate
    });
    }
    };

    // Receiving and adding a remote candidate
    const candidate = new RTCIceCandidate(receivedCandidate);
    await peerConnection.addIceCandidate(candidate);

    ICE Candidate Types:

  • host: Direct connection using local IP
  • srflx (Server Reflexive): Connection via STUN
  • relay: Connection via TURN relay
  • Connection Establishment Flow

    The Offer/Answer Model

    Peer A (Caller)                    Peer B (Callee)

    1. createOffer()
    2. setLocalDescription(offer)
    3. Send offer via signaling -->
    4. setRemoteDescription(offer)
    5. createAnswer()
    6. setLocalDescription(answer)
    <-- 7. Send answer via signaling
    8. setRemoteDescription(answer)

    <-- ICE Candidates Exchange -->

    ========= Connected =========

    Complete Connection Example

    // Peer A: Creating and sending offer
    async function createOffer() {
    const pc = new RTCPeerConnection(config);

    // Create data channel before creating offer
    const dc = pc.createDataChannel('chat');

    // Gather ICE candidates
    pc.onicecandidate = (e) => {
    if (e.candidate) {
    sendToRemote({ type: 'candidate', candidate: e.candidate });
    }
    };

    // Create and send offer
    const offer = await pc.createOffer();
    await pc.setLocalDescription(offer);
    sendToRemote({ type: 'offer', sdp: offer });

    return { pc, dc };
    }

    // Peer B: Receiving offer and sending answer
    async function handleOffer(offer) {
    const pc = new RTCPeerConnection(config);

    // Handle incoming data channel
    pc.ondatachannel = (e) => {
    const dc = e.channel;
    dc.onmessage = (msg) => console.log(msg.data);
    };

    // Gather ICE candidates
    pc.onicecandidate = (e) => {
    if (e.candidate) {
    sendToRemote({ type: 'candidate', candidate: e.candidate });
    }
    };

    // Set remote description and create answer
    await pc.setRemoteDescription(offer);
    const answer = await pc.createAnswer();
    await pc.setLocalDescription(answer);
    sendToRemote({ type: 'answer', sdp: answer });

    return pc;
    }

    Protocol Stack Deep Dive

    ICE (Interactive Connectivity Establishment)

    ICE is the framework that enables WebRTC to find the best path between peers.

    ICE Gathering States:

  • new: Gathering hasn't started
  • gathering: Collecting candidates
  • complete: All candidates gathered
  • ICE Connection States:

  • new: Initial state
  • checking: Testing connectivity
  • connected: At least one working path
  • completed: All checks complete
  • disconnected: Connectivity lost
  • failed: All candidates failed
  • closed: Connection closed
  • STUN (Session Traversal Utilities for NAT)

    STUN servers help peers discover their public IP address and port:

    Client                STUN Server



    <-- Binding Response --
    (Your public IP:
    203.0.113.50:
    54321)

    TURN (Traversal Using Relays around NAT)

    When direct connection fails, TURN relays traffic:

    Peer A <==> TURN Server <==> Peer B

    Note: Traffic is still encrypted!
    The TURN server only sees encrypted packets.

    DTLS (Datagram Transport Layer Security)

    DTLS provides encryption for all WebRTC communications:

    • Based on TLS 1.2/1.3 but for UDP
    • Mandatory in WebRTC (cannot be disabled)
    • Provides encryption, authentication, and integrity
    • Keys are derived during the DTLS handshake

    SCTP (Stream Control Transmission Protocol)

    SCTP runs over DTLS and provides data channel functionality:

    • Message-oriented (unlike TCP's byte stream)
    • Supports multiple streams over one connection
    • Configurable reliability per message
    • Handles congestion control

    Security Mechanisms

    Built-in Encryption

    All WebRTC communications are encrypted by default:

    Media Streams: SRTP (Secure RTP)
    Data Channels: DTLS + SCTP
    Key Exchange: DTLS handshake

    Certificate and Identity

    // Generate a certificate
    const certificate = await RTCPeerConnection.generateCertificate({
    name: 'ECDSA',
    namedCurve: 'P-256'
    });

    // Use it in configuration
    const pc = new RTCPeerConnection({
    certificates: [certificate],
    iceServers: [...]
    });

    // Get fingerprint for verification
    const fingerprint = certificate.getFingerprints()[0];
    console.log(fingerprint.algorithm, fingerprint.value);

    Security Considerations

    • User Consent: Browsers require explicit permission for camera/microphone
    • Secure Origins: WebRTC only works on HTTPS (or localhost)
    • No IP Leaking: Modern browsers protect against WebRTC IP leaks
    • Perfect Forward Secrecy: Each session uses unique keys

    Media Stream Handling

    MediaStream Structure

    MediaStream
    ├── MediaStreamTrack (audio)
    │ ├── id: "unique-audio-id"
    │ ├── kind: "audio"
    │ ├── label: "Built-in Microphone"
    │ └── enabled: true

    └── MediaStreamTrack (video)
    ├── id: "unique-video-id"
    ├── kind: "video"
    ├── label: "FaceTime HD Camera"
    └── enabled: true

    RTP Sender and Receiver

    // Adding a track
    const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true
    });

    stream.getTracks().forEach(track => {
    const sender = peerConnection.addTrack(track, stream);
    console.log('Added track:', track.kind);
    });

    // Receiving tracks
    peerConnection.ontrack = (event) => {
    const [remoteStream] = event.streams;
    videoElement.srcObject = remoteStream;
    };

    Advanced Features

    DTMF Support

    For telephony applications, WebRTC supports DTMF tones:

    const sender = peerConnection.getSenders()
    .find(s => s.track.kind === 'audio');

    const dtmfSender = sender.dtmf;
    dtmfSender.insertDTMF('1234', 100, 50);
    // Sends tones: 1, 2, 3, 4
    // Duration: 100ms each
    // Gap: 50ms between tones

    Statistics and Monitoring

    const stats = await peerConnection.getStats();

    stats.forEach(report => {
    if (report.type === 'candidate-pair' && report.state === 'succeeded') {
    console.log('Round-trip time:', report.currentRoundTripTime);
    console.log('Bytes sent:', report.bytesSent);
    console.log('Bytes received:', report.bytesReceived);
    }
    });

    Browser Compatibility

    WebRTC is supported in all modern browsers, but implementations vary. Use adapter.js for compatibility:

    import adapter from 'webrtc-adapter';

    console.log('Browser:', adapter.browserDetails.browser);
    console.log('Version:', adapter.browserDetails.version);

    Real-World Applications

    WebRTC powers numerous applications:

    • Video Conferencing: Google Meet, Zoom (web version)
    • File Sharing: ZeroSend, ShareDrop
    • Gaming: Real-time multiplayer games
    • IoT: Device-to-device communication
    • Live Streaming: Low-latency broadcasts
    • Customer Support: Browser-based calling

    Conclusion

    WebRTC is a powerful and complex technology that enables real-time communication directly in the browser. Understanding its layered architecture—from the high-level JavaScript APIs down to the network protocols—is essential for building robust P2P applications.

    The combination of mandatory encryption, NAT traversal mechanisms, and flexible data channels makes WebRTC the ideal foundation for privacy-focused applications like ZeroSend.

    Further Reading:

  • [MDN WebRTC API Documentation](https://developer.mozilla.org/docs/Web/API/WebRTC_API)
  • [WebRTC.org](https://webrtc.org/)
  • [IETF WebRTC Standards](https://datatracker.ietf.org/wg/rtcweb/documents/)