π RFC 6455: The WebSocket Protocol
Status: Internet Standard Last Updated: December 2011 Stability: Stable β
The foundational WebSocket protocol specification defining the framing, handshake, and core protocol mechanics.
Stay up-to-date with the evolving WebSocket ecosystem. This page tracks all WebSocket-related specifications, their current status, browser implementations, and upcoming changes that may affect your applications.
π RFC 6455: The WebSocket Protocol
Status: Internet Standard Last Updated: December 2011 Stability: Stable β
The foundational WebSocket protocol specification defining the framing, handshake, and core protocol mechanics.
π WHATWG WebSockets Living Standard
Status: Living Standard Last Updated: Continuously updated Stability: Stable with ongoing improvements β
The browser API specification defining how WebSockets work in web browsers.
ποΈ RFC 7692: Compression Extensions
Status: Proposed Standard Last Updated: December 2015 Stability: Stable with security considerations β οΈ
Defines permessage-deflate compression extension for WebSocket.
β‘ RFC 8441: HTTP/2 WebSockets
Status: Proposed Standard Last Updated: September 2018 Stability: Experimental implementation π§
Bootstrapping WebSockets over HTTP/2 using Extended CONNECT.
π RFC 9220: HTTP/3 WebSockets
Status: Proposed Standard Last Updated: June 2022 Stability: Early implementation π§
Bootstrapping WebSockets over HTTP/3 and QUIC.
β© W3C WebTransport
Status: Working Draft Last Updated: October 2024 Stability: Experimental π¬
Next-generation bidirectional communication protocol built on HTTP/3.
Feature | Chrome | Firefox | Safari | Edge |
---|---|---|---|---|
Basic WebSocket | β 16+ | β 11+ | β 7+ | β 12+ |
Binary data | β 16+ | β 11+ | β 7+ | β 12+ |
Sub-protocols | β 16+ | β 11+ | β 7+ | β 12+ |
Extensions | β 16+ | β 11+ | β 7+ | β 12+ |
Secure WebSocket (WSS) | β 16+ | β 11+ | β 7+ | β 12+ |
Feature | Chrome | Firefox | Safari | Edge |
---|---|---|---|---|
permessage-deflate | β 32+ | β 37+ | β 9+ | β 12+ |
Client context takeover | β 32+ | β 37+ | β 9+ | β 12+ |
Server context takeover | β 32+ | β 37+ | β 9+ | β 12+ |
Window bits negotiation | β 32+ | β 37+ | β 9+ | β 12+ |
Feature | Chrome | Firefox | Safari | Edge |
---|---|---|---|---|
Extended CONNECT | β 91+ | β | β | β 91+ |
pseudo-header | β 91+ | β | β | β 91+ |
SETTINGS_ENABLE_CONNECT_PROTOCOL | β 91+ | β | β | β 91+ |
Feature | Chrome | Firefox | Safari | Edge |
---|---|---|---|---|
HTTP/3 WebSocket bootstrap | π§ Experimental | β | β | π§ Experimental |
QUIC transport | β 87+ (HTTP/3) | β 88+ (HTTP/3) | β 14+ (HTTP/3) | β 87+ (HTTP/3) |
Extended CONNECT over HTTP/3 | π§ Flag required | β | β | π§ Flag required |
Feature | Chrome | Firefox | Safari | Edge |
---|---|---|---|---|
WebTransport API | β 97+ | π§ 114+ (Nightly) | β | β 97+ |
Datagrams | β 97+ | π§ | β | β 97+ |
Streams | β 97+ | π§ | β | β 97+ |
Connection pooling | β 97+ | π§ | β | β 97+ |
Server | HTTP/1.1 WebSocket | HTTP/2 WebSocket | HTTP/3 WebSocket |
---|---|---|---|
Nginx | β 1.3.13+ | β 1.25+ | π§ Experimental |
Apache | β 2.4+ (mod_proxy_wstunnel) | β | β |
Caddy | β v1+ | β v2+ | β v2.6+ |
HAProxy | β 1.4+ | β 2.0+ | π§ 2.6+ |
Node.js | β All versions | β 10.0+ | π§ Experimental |
IIS | β 8.0+ | β 10+ | β |
Provider | WebSocket Support | HTTP/2 | HTTP/3 | Notes |
---|---|---|---|---|
Cloudflare | β | β | β | 100-second timeout |
AWS CloudFront | β | β | β | Regional edge locations |
AWS ALB | β | β | β | 4000-second timeout |
Google Cloud LB | β | β | π§ | Global load balancing |
Azure App Gateway | β | β | β | Session affinity required |
Fastly | β | β | β | Real-time purging |
binaryType
behavior for ArrayBuffer// Check basic WebSocket supportif ('WebSocket' in window) { console.log('WebSocket supported');}
// Check for specific features function checkWebSocketFeatures() { constfeatures = { basic: 'WebSocket' in window, binaryType: false, compression:false, protocols: false };
if (features.basic) { try { const ws = newWebSocket('wss://echo.websocket.org'); features.binaryType = 'binaryType' in ws;features.protocols = ws.protocol !== undefined;
// Check for compression support ws.onopen = () => { features.compression = ws.extensions.includes('permessage-deflate'); ws.close(); }; } catch (e) { console.error('WebSocket test failed:', e); }
}
return features; }
// Check WebTransport support if ('WebTransport' in window) {console.log('WebTransport supported'); }
class ProtocolDetector { static async detectCapabilities() { const caps = { websocket: { basic: false, secure: false, compression: false, http2: false, http3: false }, webtransport: false, performance: {} };
// Basic WebSocket caps.websocket.basic = 'WebSocket' in window;
// Secure WebSocket if (caps.websocket.basic && location.protocol === 'https:') { try { const ws = new WebSocket('wss://echo.websocket.org'); await new Promise((resolve) => { ws.onopen = () => { caps.websocket.secure = true; caps.websocket.compression = ws.extensions.includes('permessage-deflate'); ws.close(); resolve(); }; ws.onerror = resolve; setTimeout(resolve, 5000); }); } catch (e) {} }
// WebTransport caps.webtransport = 'WebTransport' in window;
// Performance features if (window.performance && performance.timing) { caps.performance = { navigation: 'navigation' in performance, memory: 'memory' in performance, timeOrigin: 'timeOrigin' in performance }; }
return caps; }}
// Negotiate best available protocolasync function connectWithBestProtocol(url) { const caps = await ProtocolDetector.detectCapabilities();
// Try WebTransport first (if available and supported) if (caps.webtransport && url.startsWith('https://')) { try { const transport = new WebTransport(url); await transport.ready; console.log('Connected via WebTransport'); return transport; } catch (e) { console.log('WebTransport failed, falling back'); } }
// Fall back to WebSocket if (caps.websocket.secure) { const ws = new WebSocket(url.replace('https://', 'wss://')); await new Promise((resolve, reject) => { ws.onopen = resolve; ws.onerror = reject; }); console.log('Connected via WebSocket'); return ws; }
throw new Error('No suitable protocol available');}
# Nginx configuration for HTTP/2 WebSocketserver { listen 443 ssl http2; server_name example.com;
# Enable HTTP/2 WebSocket support (Nginx 1.25+) http2_recv_timeout 300s; http2_idle_timeout 300s;
location /ws { proxy_pass http://backend; proxy_http_version 1.1;
# Standard WebSocket headers proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
# HTTP/2 specific settings proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off;
# Extended CONNECT support proxy_set_header :protocol websocket; }}
// Abstraction layer for protocol migrationclass RealtimeConnection { constructor(url, options = {}) { this.url = url; this.options = options; this.protocol = null; }
async connect() { // Try WebTransport if ('WebTransport' in window && this.url.startsWith('https://')) { try { return await this.connectWebTransport(); } catch (e) { console.log('WebTransport unavailable, using WebSocket'); } }
// Fall back to WebSocket return await this.connectWebSocket(); }
async connectWebTransport() { this.transport = new WebTransport(this.url); await this.transport.ready; this.protocol = 'webtransport';
// Set up bidirectional stream const stream = await this.transport.createBidirectionalStream(); this.reader = stream.readable.getReader(); this.writer = stream.writable.getWriter();
return this; }
async connectWebSocket() { const wsUrl = this.url .replace('https://', 'wss://') .replace('http://', 'ws://');
this.ws = new WebSocket(wsUrl); this.protocol = 'websocket';
return new Promise((resolve, reject) => { this.ws.onopen = () => resolve(this); this.ws.onerror = reject; }); }
async send(data) { if (this.protocol === 'webtransport') { const encoded = new TextEncoder().encode(data); await this.writer.write(encoded); } else { this.ws.send(data); } }
async receive() { if (this.protocol === 'webtransport') { const { value } = await this.reader.read(); return new TextDecoder().decode(value); } else { return new Promise((resolve) => { this.ws.onmessage = (event) => resolve(event.data); }); } }
close() { if (this.protocol === 'webtransport') { this.transport.close(); } else { this.ws.close(); } }}
IETF httpbis Working Group: HTTP/2 and HTTP/3 WebSocket specifications
W3C WebTransport Working Group: Next-generation transport protocol
WHATWG Streams: WebSocket Living Standard
Stay informed about WebSocket standards updates with our monthly digest.
π§ Subscribe to Standards Watch
Get monthly updates on WebSocket standards and implementations delivered to your inbox.
Coming Soon - Email subscription system under development.
Follow @mattyoriordan for updates.
Track your WebSocket implementationβs compliance with the protocol specification:
# Run Autobahn TestSuitedocker run -it --rm \ -v "${PWD}/config:/config" \ -v "${PWD}/reports:/reports" \ crossbario/autobahn-testsuite \ wstest -m fuzzingclient -s /config/fuzzingclient.json
Implementation | RFC 6455 | RFC 7692 | Pass Rate |
---|---|---|---|
Chrome 120 | β 100% | β 100% | 517/517 |
Firefox 120 | β 100% | β 100% | 517/517 |
Safari 17 | β 100% | β 100% | 517/517 |
Node.js ws | β 100% | β 100% | 517/517 |
Python websockets | β 100% | β 100% | 517/517 |
Go gorilla | β 99.8% | β 100% | 516/517 |