| name | websocket |
| description | WebSocket development — real-time bidirectional communication, Socket.IO, native WebSocket API, scaling patterns. Use when working with websocket. |
| domain | development |
| author | oyi77 |
| license | Apache-2.0 |
| subdomain | software-development |
| tags | ["api","coding","software-engineering","testing","websocket"] |
| version | 1.0.0 |
Overview
WebSocket enables persistent, full-duplex communication between client and server over a single TCP connection. This skill covers the native WebSocket API, Socket.IO for feature-rich real-time apps, and scaling patterns for production deployments.
Capabilities
- Build real-time features: chat, live dashboards, notifications, collaborative editing
- Implement WebSocket servers with native
ws library or Socket.IO
- Handle connection lifecycle: open, heartbeat, reconnect, close
- Authenticate WebSocket connections during the upgrade handshake
- Scale horizontally with Redis adapter for pub/sub across instances
- Implement rooms/namespaces for message routing
- Handle backpressure and message queuing
When to Use
Trigger phrases:
-
"websocket"
-
"WebSocket development — real-time bidirectional communication, Socket"
-
Chat applications and messaging systems
-
Live dashboards and real-time data feeds
-
Collaborative editing (Google Docs-style)
-
Multiplayer games
-
Stock/crypto price streaming
-
IoT device communication
-
Progress bars and live status updates
When NOT to Use
- Task is about deployment, not development (use deploy skills)
- Task is about code review, not writing (use review skills)
- You need to understand existing code first (use research skills)
- Task is about testing only (use test skills)
- Requirements are unclear (clarify first)
- Task is trivially simple (single line fix)
Pseudo Code
The websocket workflow follows a standard pipeline pattern.
Core flow:
# websocket primary flow
input = prepare(raw_data)
result = process(input, config={bidirectional, communication, development, native, patterns})
validate(result)
deliver(result)
Error handling:
on error:
log(error_details)
retry_with_backoff(max=3)
if still_failing: alert_and_escalate()
Native WebSocket Server
const { WebSocketServer } = require('ws');
const http = require('http');
const server = http.createServer();
const wss = new WebSocketServer({ server });
wss.on('connection', (ws, req) => {
const userId = authenticateUpgrade(req);
if (!userId) {
ws.close(4001, 'Unauthorized');
return;
}
ws.isAlive = true;
ws.on('pong', () => { ws.isAlive = true; });
ws.on('message', (data) => {
const msg = JSON.parse(data);
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({ from: userId, ...msg }));
}
});
});
ws.(, .());
});
( {
wss..( {
(!ws.) ws.();
ws. = ;
ws.();
});
}, );
server.();
Socket.IO with Rooms
const { Server } = require('socket.io');
const { createAdapter } = require('@socket.io/redis-adapter');
const { createClient } = require('redis');
const io = new Server(httpServer, {
cors: { origin: 'https://app.example.com' },
});
const pubClient = createClient({ url: 'redis://localhost:6379' });
const subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);
io.adapter(createAdapter(pubClient, subClient));
io.use((socket, next) => {
const token = socket.handshake.auth.token;
const user = verifyToken(token);
if (!user) return next(new Error('Unauthorized'));
socket.user = user;
next();
});
io.(, {
.();
socket.(, {
socket.(roomId);
socket.(roomId).(, socket..);
});
socket.(, {
io.(roomId).(, {
: socket..,
text,
: .(),
});
});
socket.(, {
socket.(roomId).(, socket..);
});
socket.(, {
io.(, socket..);
});
});
Client-Side (Browser)
import { io } from 'socket.io-client';
const socket = io('https://api.example.com', {
auth: { token: getAuthToken() },
reconnection: true,
reconnectionDelay: 1000,
reconnectionAttempts: 10,
});
socket.on('connect', () => console.log('Connected:', socket.id));
socket.on('connect_error', (err) => console.error('Connection failed:', err.message));
socket.emit('join-room', 'room-123');
socket.on('new-message', (msg) => {
appendToChat(msg);
});
socket.emit('send-message', { roomId: 'room-123', text: 'Hello!' });
Reconnection with Exponential Backoff
const socket = io('https://api.example.com', {
reconnection: true,
reconnectionDelay: 1000,
reconnectionDelayMax: 30000,
reconnectionAttempts: Infinity,
});
Common Patterns
Proven patterns for websocket usage.
- Batch processing: Process multiple items in parallel for throughput
- Retry with backoff: Handle transient failures gracefully
- Rate limiting: Respect API limits with configurable delays
- Logging: Structured logging for debugging and audit trails
Namespace Isolation
const chatNs = io.of('/chat');
const notifNs = io.of('/notifications');
chatNs.on('connection', (socket) => { });
notifNs.on('connection', (socket) => { });
Binary Data Transfer
socket.emit('file-chunk', buffer);
socket.on('file-chunk', (buffer) => {
const blob = new Blob([buffer]);
});
Rate Limiting
io.use((socket, next) => {
const rateLimiter = new Map();
socket.onAny((event) => {
const now = Date.now();
const last = rateLimiter.get(event) || 0;
if (now - last < 100) return;
rateLimiter.set(event, now);
});
next();
});
How to Use
- Understand the requirement and existing codebase patterns
- Design the solution with error handling and testability in mind
- Implement incrementally with tests for each change
- Verify against expected outcomes (manual and automated)
- Document usage, edge cases, and integration points
- Review with team before merging to shared branches
Red Flags
- Skipping tests to ship faster: Untested code breaks in production when you least expect it
- No error handling in production code: Unhandled errors crash services and lose user data
- Hardcoded configuration values: Hardcoded values prevent environment switching and leak secrets
- Ignoring security implications: Missing input validation, auth bypasses, and injection vulnerabilities
- Over-engineering simple solutions: Premature abstraction adds complexity without proportional benefit
Verification
Process
- Analyze the task requirements
- Apply domain expertise
- Verify output quality
Anti-Rationalization Table
| Rationalization | Reality |
|---|
| "Tests slow me down" | Bugs slow you down 10x more. Tests are speed, not overhead. |
| "I will refactor later" | Technical debt compounds. Refactor as you go. |
| "It works on my machine" | If it is not in CI, it does not work. Ship proof, not claims. |