bookworm-smart-assistant/skills/websocket-engineer/references/protocol.md

196 lines
5.0 KiB
Markdown

# WebSocket Protocol Reference
## Protocol Basics
### Handshake Process
```
Client → Server: HTTP Upgrade Request
GET /socket.io/?EIO=4&transport=websocket HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13
Server → Client: HTTP 101 Switching Protocols
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
```
### Frame Structure
```
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
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
```
## Opcodes
```javascript
const OPCODES = {
CONTINUATION: 0x0, // Continuation frame
TEXT: 0x1, // Text frame
BINARY: 0x2, // Binary frame
CLOSE: 0x8, // Connection close
PING: 0x9, // Heartbeat ping
PONG: 0xA // Heartbeat pong
};
```
## Ping/Pong Mechanism
```javascript
// Server-side ping/pong with ws library
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
ws.isAlive = true;
ws.on('pong', () => {
ws.isAlive = true;
});
ws.on('message', (data) => {
console.log('Received:', data);
});
});
// Ping clients every 30 seconds
const interval = setInterval(() => {
wss.clients.forEach((ws) => {
if (ws.isAlive === false) {
return ws.terminate();
}
ws.isAlive = false;
ws.ping(); // Send ping frame
});
}, 30000);
wss.on('close', () => {
clearInterval(interval);
});
```
## Close Codes
```javascript
const CLOSE_CODES = {
1000: 'Normal Closure',
1001: 'Going Away',
1002: 'Protocol Error',
1003: 'Unsupported Data',
1005: 'No Status Received',
1006: 'Abnormal Closure',
1007: 'Invalid Payload',
1008: 'Policy Violation',
1009: 'Message Too Big',
1010: 'Mandatory Extension',
1011: 'Internal Server Error',
1015: 'TLS Handshake Fail'
};
// Proper close handling
ws.close(1000, 'Normal closure');
```
## Message Size Limits
```javascript
// Set max payload size (default 100MB)
const wss = new WebSocket.Server({
port: 8080,
maxPayload: 1024 * 1024 // 1MB
});
// Handle too large messages
ws.on('error', (error) => {
if (error.message.includes('Max payload size exceeded')) {
ws.close(1009, 'Message too big');
}
});
```
## Compression (permessage-deflate)
```javascript
const wss = new WebSocket.Server({
port: 8080,
perMessageDeflate: {
zlibDeflateOptions: {
chunkSize: 1024,
memLevel: 7,
level: 3
},
zlibInflateOptions: {
chunkSize: 10 * 1024
},
clientNoContextTakeover: true,
serverNoContextTakeover: true,
serverMaxWindowBits: 10,
concurrencyLimit: 10,
threshold: 1024 // Only compress messages > 1KB
}
});
```
## Binary Data Handling
```javascript
// Send binary data
const buffer = Buffer.from([0x00, 0x01, 0x02, 0x03]);
ws.send(buffer, { binary: true });
// Receive binary data
ws.on('message', (data) => {
if (data instanceof Buffer) {
console.log('Received binary:', data);
} else {
console.log('Received text:', data.toString());
}
});
// ArrayBuffer in browser
socket.binaryType = 'arraybuffer';
socket.onmessage = (event) => {
if (event.data instanceof ArrayBuffer) {
const view = new Uint8Array(event.data);
console.log('Received:', view);
}
};
```
## Protocol Comparison
| Feature | WebSocket | Socket.IO |
|---------|-----------|-----------|
| Protocol | Native WS | WS + fallbacks |
| Handshake | HTTP Upgrade | Engine.IO handshake |
| Reconnection | Manual | Automatic |
| Broadcasting | Manual | Built-in |
| Rooms | Manual | Built-in |
| Acknowledgments | Manual | Built-in |
| Binary | Native | Converted |
| Overhead | Minimal | Higher |
| Fallback | None | Long polling, SSE |