Back
Loading views...WebSocket
WebSocket
Category: Networking/IoT
Overview
WebSocket is a full-duplex communication protocol over a single TCP connection, standardized by RFC 6455. It enables real-time bidirectional communication between web browsers/clients and servers, eliminating the overhead of repeated HTTP polling. Used in embedded systems for IoT dashboards, real-time control, and firmware update interfaces.
1. Theory & Fundamentals
- Starts as HTTP upgrade handshake; then switches to WebSocket protocol
- Full-duplex: Server and client can send at any time without request
- Port: 80 (ws://) or 443 (wss:// with TLS)
- Framing: Efficient binary or text frames
- Ping/Pong: Keepalive mechanism
- Subprotocols: Negotiate application protocol over WebSocket
- Low overhead: 2–14 byte frame header vs HTTP headers per request
2. Frame / Packet Structure
WebSocket Frame:
FIN(1) | RSV(3) | Opcode(4) | MASK(1) | Payload Len(7) [+ Extended] | [Masking Key(4)] | Payload
Opcodes:
0x0 = Continuation
0x1 = Text frame
0x2 = Binary frame
0x8 = Close
0x9 = Ping
0xA = Pong
Client→Server: MASK=1 (all client frames masked with 4-byte XOR key)
Server→Client: MASK=0
HTTP Upgrade Handshake:
GET /ws HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: <base64 random>
Server responds 101 Switching Protocols + Sec-WebSocket-Accept
3. Protocol Mechanics
- Handshake: Single HTTP upgrade; no repeated headers
- Framing: Variable-length with efficient header
- Masking: Client must mask; prevents cache poisoning by proxies
- Close: Both sides send Close frame; TCP connection terminates gracefully
- Ping/Pong: Server pings; client responds with Pong (or vice versa)
4. Hardware Implementation
- ESP32: WiFi + WebSocket server library (arduinoWebSockets, ESP-IDF)
- Raspberry Pi: Any language (Python websockets, Node.js ws)
- STM32 + W5500: Ethernet + WebSocket library
- RTOS: FreeRTOS + LwIP + WebSocket server
- Client: Browser JavaScript WebSocket API; any language library
5. Register-Level / Configuration
// ESP32 Arduino WebSocket server
#include <WebSocketsServer.h>
WebSocketsServer ws = WebSocketsServer(81);
void wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t len) {
if(type == WStype_TEXT) {
Serial.printf("Client %d: %s
", num, payload);
ws.sendTXT(num, "{"ack":true}");
}
}
void setup() {
WiFi.begin(ssid, password);
ws.begin();
ws.onEvent(wsEvent);
}
void loop() {
ws.loop();
// Push sensor data to all clients
static uint32_t last = 0;
if(millis()-last > 1000) {
String msg = "{"temp":"+String(readTemp())+"}";
ws.broadcastTXT(msg);
last = millis();
}
}
6. Driver / Software Development
# Python asyncio WebSocket server
import asyncio, websockets, json
async def handler(ws, path):
async for msg in ws:
data = json.loads(msg)
if data['cmd'] == 'get_temp':
await ws.send(json.dumps({'temp': 23.5}))
asyncio.get_event_loop().run_until_complete(
websockets.serve(handler, '0.0.0.0', 8765))
7. Debugging & Testing
- Browser DevTools → Network → WS tab: See WebSocket frames
- Postman: WebSocket testing built in
- wscat CLI:
wscat -c ws://device.local:81 - Wireshark: WebSocket dissector (see HTTP upgrade + frames)
- Common issues: CORS policy; proxy stripping Upgrade header; TLS cert mismatch
8. Real-World Applications
- IoT device real-time dashboard (live sensor graphs)
- Web-based firmware update interface
- Real-time control of robotic systems
- Live trading data feeds
- Multiplayer embedded game state sync
9. Advanced Topics & Edge Cases
- WS over MQTT: Some brokers expose WebSocket endpoint for browser clients
- Socket.IO: Built on WebSocket with fallback polling; adds rooms, events
- WSS (WebSocket Secure): TLS required for production
- Binary protocol: More efficient than JSON for high-frequency sensor data
- Load balancing: Sticky sessions required for stateful WebSocket connections
10. Standards & Variants
| Standard | Notes |
|---|---|
| RFC 6455 | WebSocket core protocol |
| RFC 7692 | Per-message compression |
| Socket.IO | WebSocket + polling fallback |
| STOMP over WS | Messaging protocol over WebSocket |
| WAMP | WebSocket Application Messaging Protocol |
💡 Practical Examples
Example 1: ESP32 WebSocket telemetry
ws.broadcastTXT("{"rpm":3500,"temp":85.2}"); // Send to all clients
Example 2: Browser client
const ws = new WebSocket('ws://192.168.1.100:81');
ws.onmessage = (e) => { const d=JSON.parse(e.data); updateChart(d.temp); };
ws.send(JSON.stringify({cmd: 'set_output', value: 1}));
Example 3: Binary sensor stream
uint8_t buf[8]; memcpy(buf, &float_val, 4); // Pack float
ws.broadcastBIN(buf, 8); // More efficient than JSON string
🧪 Practice Questions
Beginner
- What protocol does WebSocket upgrade from?
- Is WebSocket full-duplex?
- What is the difference between ws:// and wss://?
- What does MASK bit mean?
- What are WebSocket opcodes?
Intermediate
- Implement WebSocket handshake from scratch (Sec-WebSocket-Accept calculation).
- Handle multiple concurrent WebSocket clients on ESP32.
- What is WebSocket per-message compression?
- Implement binary frame protocol for efficient sensor streaming.
- How do you handle WebSocket reconnection in a client?
Advanced
- Build a WebSocket server on FreeRTOS + LwIP without Arduino.
- Implement load-balanced WebSocket cluster with Redis pub/sub.
- Secure WebSocket with TLS (WSS) and client certificate.
- Implement WAMP protocol over WebSocket for RPC.
- Compare WebSocket vs SSE vs HTTP/2 for IoT telemetry.
Hands-on Projects
- Live Dashboard: ESP32 sensor → WebSocket → Browser chart (Chart.js).
- Remote Control: WebSocket-based web UI to control GPIO over LAN.
- Firmware Updater: Upload firmware via WebSocket binary transfer.
Checklist
- [ ] Explain WebSocket handshake and frame format
- [ ] Implement WebSocket server on ESP32
- [ ] Implement WebSocket client in Python and JavaScript
- [ ] Handle text and binary frames
- [ ] Broadcast to multiple clients
- [ ] Implement ping/pong keepalive
- [ ] Secure with TLS (WSS)
- [ ] Debug with browser DevTools
- [ ] Build live sensor dashboard
- [ ] Handle reconnection gracefully