Introduction: Real-Time Communication
HTTP's request-response model doesn't work for real-time applications. When you need instant updates—chat messages, live scores, video calls—you need protocols designed for bidirectional, low-latency communication.
Series Context: This is Part 11 of 20 in the Complete Protocols Master series. Real-time protocols operate at the Application Layer, often building on TCP (WebSockets), UDP (RTP), or both (WebRTC).
1
Part 1: OSI Model & Protocol Foundations
Network layers, encapsulation, TCP/IP model
2
Physical & Data Link Layers
Ethernet, Wi-Fi, VLANs, MAC addressing
3
Network Layer & IP
IPv4, IPv6, ICMP, routing protocols
4
Transport Layer
TCP, UDP, QUIC, ports, sockets
5
Session & Presentation Layers
TLS handshake, encryption, serialization
6
Web Protocols
HTTP/1.1, HTTP/2, HTTP/3, WebSockets
7
API Protocols
REST, GraphQL, gRPC, SOAP
8
DNS Deep Dive
DNS hierarchy, records, DNSSEC
9
Email Protocols
SMTP, IMAP, POP3, SPF/DKIM/DMARC
10
File Transfer Protocols
FTP, SFTP, SCP, rsync
11
Real-Time Protocols
WebRTC, SIP, RTP, VoIP
You Are Here
12
Streaming Protocols
HLS, DASH, RTMP, media delivery
13
IoT Protocols
MQTT, CoAP, Zigbee, LoRaWAN
14
VPN & Tunneling
IPsec, OpenVPN, WireGuard
15
Authentication Protocols
OAuth, SAML, OIDC, Kerberos
16
Network Management
SNMP, NetFlow, Syslog
17
Security Protocols
TLS/SSL, certificates, PKI
18
Cloud Provider Protocols
AWS, Azure, GCP APIs
19
Emerging Protocols
QUIC, HTTP/3, WebTransport
20
Web Security Standards
CORS, CSP, HSTS, SRI
Overview
Real-Time Protocol Landscape
| Protocol | Use Case | Transport | Browser Support |
| WebSockets | Bidirectional messaging | TCP | ✅ Native |
| SSE | Server push (one-way) | HTTP | ✅ Native |
| WebRTC | P2P audio/video | UDP/TCP | ✅ Native |
| SIP | Call signaling | TCP/UDP | ❌ SIP.js |
| RTP | Media streaming | UDP | Via WebRTC |
| XMPP | IM/Presence | TCP | Stanza.io |
# Real-time vs Request-Response
# HTTP: Request-Response
# Client: "Any new messages?"
# Server: "No"
# (1 second later)
# Client: "Any new messages?"
# Server: "No"
# (Polling wastes bandwidth, adds latency)
# WebSocket: Bidirectional
# Client: "Open connection"
# Server: "Connected"
# Server: "New message: Hello!" (instant push)
# Client: "Send: Hi back!"
# (Connection stays open)
# Key differences:
comparison = {
"HTTP Polling": {
"connection": "Open, close, repeat",
"latency": "High (request interval)",
"bandwidth": "High (headers each time)",
"bidirectional": False
},
"WebSocket": {
"connection": "Persistent",
"latency": "Low (instant)",
"bandwidth": "Low (minimal framing)",
"bidirectional": True
}
}
for proto, features in comparison.items():
print(f"\n{proto}:")
for key, value in features.items():
print(f" {key}: {value}")
WebSockets
WebSockets (RFC 6455) provide full-duplex communication over a single TCP connection. They're the foundation of real-time web applications—chat, gaming, live updates.
Handshake
WebSocket Connection Upgrade
WebSocket starts as HTTP, then upgrades:
CLIENT REQUEST:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
SERVER RESPONSE:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
After this handshake:
• No more HTTP headers
• Binary framing only
• Full-duplex communication
• Either side can send anytime
# WebSocket server with Python (websockets library)
async def websocket_server_example():
"""WebSocket server demonstration"""
print("WebSocket Server Example")
print("=" * 50)
print("""
import asyncio
import websockets
# Store connected clients
clients = set()
async def handler(websocket, path):
# Register client
clients.add(websocket)
try:
async for message in websocket:
print(f"Received: {message}")
# Broadcast to all clients
for client in clients:
if client != websocket:
await client.send(f"User said: {message}")
finally:
clients.remove(websocket)
# Start server
async def main():
async with websockets.serve(handler, "localhost", 8765):
print("WebSocket server running on ws://localhost:8765")
await asyncio.Future() # Run forever
asyncio.run(main())
""")
print("\nInstall: pip install websockets")
asyncio.run(websocket_server_example()) if 'asyncio' in dir() else websocket_server_example()
// WebSocket client (JavaScript)
// Browser WebSocket API
const socket = new WebSocket('wss://server.example.com/chat');
// Connection opened
socket.addEventListener('open', (event) => {
console.log('Connected!');
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', (event) => {
console.log('Message from server:', event.data);
});
// Connection closed
socket.addEventListener('close', (event) => {
console.log('Disconnected');
});
// Handle errors
socket.addEventListener('error', (error) => {
console.error('WebSocket error:', error);
});
// Send message
function sendMessage(text) {
if (socket.readyState === WebSocket.OPEN) {
socket.send(text);
}
}
// Close connection
function disconnect() {
socket.close();
}
Socket.io
Socket.io: WebSocket with Fallbacks
// Socket.io adds: reconnection, rooms, namespaces
// Server (Node.js)
const io = require('socket.io')(3000);
io.on('connection', (socket) => {
console.log('Client connected:', socket.id);
// Join a room
socket.join('room-123');
// Listen for events
socket.on('chat message', (msg) => {
// Broadcast to room
io.to('room-123').emit('chat message', msg);
});
socket.on('disconnect', () => {
console.log('Client disconnected');
});
});
// Client (Browser)
const socket = io('http://localhost:3000');
socket.on('connect', () => {
console.log('Connected!');
});
socket.emit('chat message', 'Hello everyone!');
socket.on('chat message', (msg) => {
console.log('Message:', msg);
});
Server-Sent Events (SSE)
SSE provides one-way server-to-client streaming over HTTP. Simpler than WebSockets when you only need server push (notifications, live feeds).
SSE vs WebSocket
When to Use SSE
SSE Advantages:
• Simpler than WebSocket
• Works over HTTP/2 (multiplexing)
• Auto-reconnection built-in
• Event IDs for resume after disconnect
SSE Limitations:
• One-way only (server → client)
• Text data only (no binary)
• Limited connections per browser (6 HTTP/1.1)
Use SSE for:
✅ Live scores
✅ News feeds
✅ Notifications
✅ Stock tickers
Use WebSocket for:
✅ Chat (bidirectional)
✅ Gaming (low latency)
✅ Collaborative editing
# SSE server with Python (Flask)
from flask import Flask, Response
import time
app = Flask(__name__)
def generate_events():
"""Generator for SSE events"""
count = 0
while True:
count += 1
# SSE format: data: message\n\n
yield f"data: Event {count} at {time.strftime('%H:%M:%S')}\n\n"
time.sleep(1)
@app.route('/events')
def events():
return Response(
generate_events(),
mimetype='text/event-stream',
headers={
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
}
)
# Run: flask run
# Client connects to /events and receives stream
// SSE client (JavaScript)
// Create EventSource
const eventSource = new EventSource('/events');
// Listen for messages
eventSource.onmessage = (event) => {
console.log('Received:', event.data);
};
// Named events
eventSource.addEventListener('notification', (event) => {
console.log('Notification:', event.data);
});
// Error handling (auto-reconnects)
eventSource.onerror = (error) => {
console.error('SSE error:', error);
};
// Close connection
// eventSource.close();
WebRTC: Browser Peer-to-Peer
WebRTC (Web Real-Time Communication) enables peer-to-peer audio, video, and data directly between browsers—no plugins needed. Powers video calls, screen sharing, and file transfer.
P2P But Needs Servers: WebRTC is peer-to-peer for media, but still needs: (1) Signaling server to exchange connection info, (2) STUN/TURN servers to traverse NAT/firewalls.
Architecture
WebRTC Connection Flow
WebRTC Connection Steps:
1. SIGNALING (via WebSocket/HTTP)
• Exchange SDP (Session Description Protocol)
• Describes media capabilities
2. ICE CANDIDATE GATHERING
• STUN: Discover public IP/port
• TURN: Relay if direct P2P fails
3. ICE CONNECTIVITY CHECKS
• Try all candidate pairs
• Select best path (usually direct P2P)
4. DTLS HANDSHAKE
• Secure the connection
• Exchange encryption keys
5. MEDIA/DATA FLOW
• SRTP for audio/video (encrypted RTP)
• SCTP for data channels
STUN vs TURN:
STUN: "What's my public IP?" (cheap, just discovery)
TURN: "Relay my traffic" (expensive, when P2P fails)
// WebRTC peer connection example
// Create peer connection
const config = {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{
urls: 'turn:turn.example.com',
username: 'user',
credential: 'pass'
}
]
};
const pc = new RTCPeerConnection(config);
// Handle ICE candidates
pc.onicecandidate = (event) => {
if (event.candidate) {
// Send candidate to peer via signaling server
sendToSignaling({ type: 'candidate', candidate: event.candidate });
}
};
// Handle incoming tracks (audio/video)
pc.ontrack = (event) => {
document.getElementById('remoteVideo').srcObject = event.streams[0];
};
// Add local media
async function startCall() {
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
// Show local video
document.getElementById('localVideo').srcObject = stream;
// Add tracks to peer connection
stream.getTracks().forEach(track => pc.addTrack(track, stream));
// Create and send offer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
sendToSignaling({ type: 'offer', sdp: offer });
}
// Handle incoming offer
async function handleOffer(offer) {
await pc.setRemoteDescription(new RTCSessionDescription(offer));
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
sendToSignaling({ type: 'answer', sdp: answer });
}
// Handle incoming answer
async function handleAnswer(answer) {
await pc.setRemoteDescription(new RTCSessionDescription(answer));
}
// Handle incoming ICE candidate
async function handleCandidate(candidate) {
await pc.addIceCandidate(new RTCIceCandidate(candidate));
}
Data Channels
WebRTC for Data (Not Just Video)
// WebRTC Data Channels: P2P data transfer
const pc = new RTCPeerConnection(config);
// Create data channel (initiator)
const dataChannel = pc.createDataChannel('chat', {
ordered: true, // Guarantee order
maxRetransmits: 3 // Reliability
});
dataChannel.onopen = () => {
console.log('Data channel open');
dataChannel.send('Hello peer!');
};
dataChannel.onmessage = (event) => {
console.log('Received:', event.data);
};
// Handle incoming data channel (responder)
pc.ondatachannel = (event) => {
const channel = event.channel;
channel.onmessage = (e) => console.log('Received:', e.data);
};
// Use cases:
// • P2P file transfer (no server storage!)
// • Low-latency gaming
// • Collaborative editing
SIP & RTP: VoIP Protocols
SIP (Session Initiation Protocol) handles call signaling—ringing, answering, hanging up. RTP (Real-time Transport Protocol) carries the actual audio/video.
SIP Basics
SIP Call Flow
SIP Call Setup:
Alice Server Bob
| | |
|------ INVITE ------>| |
| |------ INVITE ------>|
| |<----- 180 Ringing --|
|<---- 180 Ringing ---| |
| |<----- 200 OK -------|
|<---- 200 OK --------| |
|------- ACK -------->| |
| |------- ACK -------->|
| | |
|<========== RTP Media Flow =============>|
| | |
|------- BYE -------->| |
| |------- BYE -------->|
| |<----- 200 OK -------|
|<---- 200 OK --------| |
SIP Methods:
INVITE - Start call
ACK - Confirm INVITE
BYE - End call
CANCEL - Cancel pending INVITE
REGISTER - Register with server
OPTIONS - Query capabilities
# SIP INVITE message example
INVITE sip:bob@example.com SIP/2.0
Via: SIP/2.0/UDP alice-pc.example.com:5060
From: "Alice" <sip:alice@example.com>;tag=1234
To: "Bob" <sip:bob@example.com>
Call-ID: 987654321@alice-pc.example.com
CSeq: 1 INVITE
Contact: <sip:alice@alice-pc.example.com:5060>
Content-Type: application/sdp
Content-Length: 200
v=0
o=alice 2890844526 2890844526 IN IP4 alice-pc.example.com
s=Phone Call
c=IN IP4 alice-pc.example.com
t=0 0
m=audio 49170 RTP/AVP 0 8 97
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 opus/48000/2
RTP
RTP: Real-time Transport Protocol
RTP Header (12 bytes minimum):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload |
Key Fields:
V = Version (2)
PT = Payload Type (codec: 0=PCMU, 8=PCMA, etc.)
Sequence = Order packets (detect loss)
Timestamp = Synchronize playback
SSRC = Source identifier
RTP uses UDP because:
• Low latency (no retransmission delay)
• Packet loss acceptable (brief glitch vs delay)
• Timing critical (can't wait for retransmit)
XMPP: Extensible Messaging
XMPP (Extensible Messaging and Presence Protocol) is an open standard for instant messaging, presence, and multi-user chat. Used by WhatsApp (modified), Google Talk, and many enterprise chat systems.
XMPP Stanzas
XMPP Message Format (XML)
<!-- Message Stanza -->
<message from="alice@example.com"
to="bob@example.com"
type="chat">
<body>Hello Bob!</body>
</message>
<!-- Presence Stanza -->
<presence from="alice@example.com">
<show>away</show>
<status>In a meeting</status>
</presence>
<!-- IQ (Info/Query) Stanza -->
<iq type="get" id="roster1">
<query xmlns="jabber:iq:roster"/>
</iq>
XMPP Stanza Types:
• message - Chat messages
• presence - Online status
• iq - Request/response queries
# XMPP client example (slixmpp library)
def demonstrate_xmpp():
"""Show XMPP concepts"""
print("XMPP Example (slixmpp)")
print("=" * 50)
print("""
import slixmpp
class ChatBot(slixmpp.ClientXMPP):
def __init__(self, jid, password):
super().__init__(jid, password)
# Event handlers
self.add_event_handler('session_start', self.start)
self.add_event_handler('message', self.message)
async def start(self, event):
# Send presence
self.send_presence()
# Get contact list
await self.get_roster()
def message(self, msg):
if msg['type'] == 'chat':
print(f"From {msg['from']}: {msg['body']}")
# Reply
msg.reply(f"You said: {msg['body']}").send()
# Connect
bot = ChatBot('bot@example.com', 'password')
bot.connect()
bot.process(forever=True)
""")
print("\nXMPP Features:")
print("• Federated (anyone can run a server)")
print("• Multi-user chat (MUC) rooms")
print("• End-to-end encryption (OMEMO)")
print("• Extensible via XEPs")
demonstrate_xmpp()
Protocol Comparison
Decision Guide
Choosing the Right Protocol
| Use Case | Best Choice | Reason |
| Chat application | WebSocket / Socket.io | Bidirectional, low latency |
| Live notifications | SSE | Simpler, HTTP/2 friendly |
| Video conferencing | WebRTC | P2P, low latency |
| VoIP / PBX | SIP + RTP | Standard, interoperable |
| IM with presence | XMPP | Federated, feature-rich |
| Gaming (browser) | WebSocket + WebRTC | Low latency, P2P data |
| Stock ticker | SSE | One-way, auto-reconnect |
# Protocol selection helper
def recommend_protocol(use_case):
"""Recommend real-time protocol based on use case"""
recommendations = {
"bidirectional_chat": {
"protocol": "WebSocket",
"library": "Socket.io / ws",
"reason": "Full-duplex, reliable delivery"
},
"server_notifications": {
"protocol": "Server-Sent Events",
"library": "Native EventSource",
"reason": "Simple, auto-reconnect, HTTP/2"
},
"video_call": {
"protocol": "WebRTC",
"library": "Simple-peer / Mediasoup",
"reason": "P2P, low latency, native browser"
},
"voip_pbx": {
"protocol": "SIP + RTP",
"library": "Opal / FreeSWITCH",
"reason": "Telephony standard, PSTN interop"
},
"file_transfer_p2p": {
"protocol": "WebRTC Data Channel",
"library": "Simple-peer",
"reason": "Direct P2P, no server storage"
},
"live_collaboration": {
"protocol": "WebSocket + OT/CRDT",
"library": "Y.js / ShareDB",
"reason": "Real-time sync, conflict resolution"
}
}
if use_case in recommendations:
rec = recommendations[use_case]
return f"{rec['protocol']} ({rec['library']}) - {rec['reason']}"
return "WebSocket (general purpose)"
print("Protocol Recommendations")
print("=" * 50)
for case in ["bidirectional_chat", "server_notifications", "video_call", "voip_pbx"]:
print(f"\n{case}:")
print(f" → {recommend_protocol(case)}")
Summary & Next Steps
Key Takeaways:
- WebSocket: Bidirectional over TCP, foundation for real-time web
- SSE: Server push only, simpler than WebSocket
- WebRTC: P2P audio/video/data, requires signaling
- SIP/RTP: VoIP standard, telephony interoperability
- XMPP: Open IM standard, federated architecture
Quiz
Test Your Knowledge
- WebSocket vs HTTP difference? (Persistent, bidirectional)
- When to use SSE over WebSocket? (Server-push only, simpler)
- Why does WebRTC need signaling? (Exchange SDP, ICE candidates)
- STUN vs TURN? (Discovery vs relay)
- What protocol carries VoIP audio? (RTP)
Related Articles
Part 10: File Transfer Protocols
FTP, SFTP, SCP, and rsync for file transfer.
Read Article
Part 12: Streaming Protocols
HLS, DASH, RTMP for video delivery.
Read Article