WebSocket Protocol Overview — Understanding the Real-Time Communication Standard
In this tutorial, you will learn about Websocket Protocol Overview. We cover key concepts, practical examples, and best practices to help you master this topic.
WebSocket is a standardized protocol (RFC 6455) that provides full-duplex communication over a single TCP connection, starting with an HTTP upgrade handshake and transitioning to a framed message protocol.
What You'll Learn
- How the WebSocket handshake upgrades HTTP to WebSocket
- The WebSocket frame format and opcodes
- How masking works in WebSocket
Why It Matters
Understanding the protocol helps you debug connection issues, optimize performance, and implement custom WebSocket clients when needed. Many problems with WebSocket (disconnections, data corruption, proxy issues) trace back to protocol misunderstandings.
Real-World Use
DodaTech's real-time collaboration platform uses WebSocket for document editing. The handshake upgrades the HTTP connection, then all communication uses framed binary messages with opcode 2 for efficient data transfer.
sequenceDiagram
participant Client
participant Server
Client->>Server: GET /ws HTTP/1.1
Client->>Server: Upgrade: websocket
Client->>Server: Connection: Upgrade
Client->>Server: Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Client->>Server: Sec-WebSocket-Version: 13
Server-->>Client: HTTP 101 Switching Protocols
Server-->>Client: Upgrade: websocket
Server-->>Client: Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Note over Client,Server: Full-duplex communication begins
Client->>Server: WebSocket Frame (text/binary)
Server-->>Client: WebSocket Frame (text/binary)
Handshake Implementation
import hashlib
import base64
def compute_websocket_accept(key):
"""Compute the expected Sec-WebSocket-Accept value"""
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
sha1 = hashlib.sha1((key + GUID).encode()).digest()
return base64.b64encode(sha1).decode()
def verify_handshake(headers):
"""Verify a WebSocket upgrade request"""
upgrade = headers.get('Upgrade', '').lower()
connection = headers.get('Connection', '').lower()
ws_key = headers.get('Sec-WebSocket-Key')
ws_version = headers.get('Sec-WebSocket-Version')
if 'websocket' not in upgrade:
return False, "Missing Upgrade: websocket"
if 'upgrade' not in connection:
return False, "Missing Connection: Upgrade"
if not ws_key:
return False, "Missing Sec-WebSocket-Key"
if ws_version != '13':
return False, "Only version 13 supported"
return True, compute_websocket_accept(ws_key)
Frame Parsing
def parse_websocket_frame(data):
"""Parse a WebSocket frame from raw bytes"""
if len(data) < 2:
return None
first_byte = data[0]
second_byte = data[1]
fin = (first_byte >> 7) & 1
opcode = first_byte & 0x0F
masked = (second_byte >> 7) & 1
payload_length = second_byte & 0x7F
offset = 2
if payload_length == 126:
payload_length = int.from_bytes(data[2:4], 'big')
offset = 4
elif payload_length == 127:
payload_length = int.from_bytes(data[2:10], 'big')
offset = 10
masking_key = None
if masked:
masking_key = data[offset:offset + 4]
offset += 4
payload = data[offset:offset + payload_length]
if masking_key:
payload = bytes(
payload[i] ^ masking_key[i % 4]
for i in range(len(payload))
)
return {
'fin': fin,
'opcode': opcode,
'masked': masked,
'payload_length': payload_length,
'payload': payload
}
Common Mistakes
1. Not Handling the 101 Response Properly
The server must return HTTP 101 Switching Protocols. Returning 200 or any other status breaks the upgrade.
2. Forgetting the Masking Bit
Client-to-server frames must be masked. Server-to-client frames must not be masked. Violating this causes the connection to close.
3. Incorrect Sec-WebSocket-Accept Computation
The accept value is SHA-1 of key + GUID. Wrong GUID or hash algorithm produces an incorrect accept value.
4. Not Handling Fragmented Frames
Large messages are fragmented. FIN=0 indicates more frames follow. The receiver must reassemble fragments until FIN=1.
5. Ignoring Close Frame Codes
The close frame contains a status code. Codes 1000-1015 have specific meanings. Ignoring them hides connection issues.
Practice Questions
- What HTTP status code completes the WebSocket handshake?
- What header must the client include in the upgrade request?
- Are client-to-server frames masked?
- What is the WebSocket GUID?
- How are large messages handled?
Answers
- 101 Switching Protocols. 2. Sec-WebSocket-Key. 3. Yes, client-to-server frames must be masked. 4. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11". 5. They are fragmented into multiple frames with FIN=0 until the final frame with FIN=1.
Challenge
Build a minimal WebSocket server from scratch using raw TCP sockets that: validates the HTTP upgrade handshake, computes the correct accept key, parses incoming masked frames, sends unmasked frames, handles ping/pong, and properly closes connections.
FAQ
Mini Project
Build a WebSocket debugging tool that: captures WebSocket handshake requests, validates headers, parses frames and displays opcodes and payload, logs close codes with explanations, and simulates different WebSocket scenarios for testing.
What's Next
- Learn about WebSocket handshake details
- Explore WebSocket frame format and opcodes
- Continue to close codes and connection management
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro