WebSocket connections require careful handling of authentication, reconnection, room management, and rate limiting. Claude Code can generate production-ready socket.io implementations when given the right patterns.
CLAUDE.md for WebSocket Standards
## WebSocket Rules
### Server-side
- Library: socket.io (namespaces, rooms, reconnect built-in)
- All connections require JWT auth (verify in handshake)
- Room naming: `{type}:{id}` e.g. `room:uuid`, `user:userId`
- Event names: snake_case — `message_sent`, `user_joined`
### Security
- Message size limit: 64KB (maxHttpBufferSize)
- Rate limiting: 60 messages/minute/user
- Escape all message content (XSS prevention)
### Client-side
- Reconnection: max 5 attempts, exponential backoff
- Show connection status in UI
- Always cleanup: socket.disconnect() on component unmount
Generating the Socket.io Server
Generate a WebSocket server using socket.io.
Requirements:
- JWT authentication (verify auth token in handshake)
- Chat room functionality (join/leave/message)
- Redis for online user presence tracking
- Rate limiting (60 messages/minute/user)
- TypeScript
Generate these files:
- src/websocket/server.ts
- src/websocket/handlers/chatHandler.ts
- src/websocket/middleware/authMiddleware.ts
- src/websocket/services/presenceService.ts
Generated Server Structure
// src/websocket/server.ts
import { Server } from 'socket.io';
import { verifyToken } from './middleware/authMiddleware';
import { registerChatHandlers } from './handlers/chatHandler';
export function initWebSocket(httpServer: HttpServer): Server {
const io = new Server(httpServer, {
cors: { origin: process.env.CLIENT_URL, credentials: true },
maxHttpBufferSize: 64 * 1024, // 64KB limit
});
io.use(verifyToken); // JWT auth middleware
io.on('connection', (socket) => {
registerChatHandlers(io, socket);
socket.on('disconnect', (reason) => {
// cleanup presence
});
});
return io;
}
// src/websocket/handlers/chatHandler.ts
export function registerChatHandlers(io: Server, socket: Socket) {
socket.on('join_room', async ({ roomId }) => {
socket.join(`room:${roomId}`);
socket.to(`room:${roomId}`).emit('user_joined', {
userId: socket.data.userId,
timestamp: Date.now(),
});
});
socket.on('send_message', rateLimit(60, async ({ roomId, content }) => {
const sanitized = escapeHtml(content);
if (sanitized.length > 1000) return;
io.to(`room:${roomId}`).emit('message_received', {
userId: socket.data.userId,
content: sanitized,
timestamp: Date.now(),
});
}));
socket.on('leave_room', ({ roomId }) => {
socket.leave(`room:${roomId}`);
socket.to(`room:${roomId}`).emit('user_left', {
userId: socket.data.userId,
});
});
}
Client-Side Reconnection Hook
Generate a socket.io client reconnection hook (React + TypeScript).
Requirements:
- Reconnect: max 5 attempts, exponential backoff (1s, 2s, 4s, 8s, 16s)
- Track connection status: connecting/connected/disconnected/failed
- Show spinner during reconnecting
- Show "Please refresh the page" after 5 failed attempts
- Cleanup: socket.disconnect() on useEffect cleanup
Save to: src/hooks/useWebSocket.ts
Generated hook:
type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'failed';
export function useWebSocket(roomId: string) {
const [status, setStatus] = useState<ConnectionStatus>('connecting');
const socketRef = useRef<Socket | null>(null);
useEffect(() => {
const socket = io(process.env.REACT_APP_WS_URL!, {
auth: { token: getAuthToken() },
reconnectionAttempts: 5,
reconnectionDelay: 1000,
reconnectionDelayMax: 16000,
});
socket.on('connect', () => setStatus('connected'));
socket.on('disconnect', () => setStatus('disconnected'));
socket.on('reconnect_failed', () => setStatus('failed'));
socketRef.current = socket;
return () => {
socket.disconnect();
};
}, [roomId]);
return { socket: socketRef.current, status };
}
Testing WebSocket Handlers
Generate unit tests for the socket.io server.
Test cases:
- Valid JWT connects successfully
- Invalid JWT is rejected on connection
- join_room adds socket to correct room
- send_message broadcasts to room members only
- Rate limit exceeded — message is silently ignored
- XSS content is escaped before broadcast
Tools: vitest + socket.io-client (test client)
Save to: src/websocket/__tests__/chatHandler.test.ts
Summary
Design WebSocket implementations with Claude Code:
- CLAUDE.md — Define connection rules, security limits, event naming
- socket.io server — JWT auth, rooms, rate limiting from the prompt
- Client hook — Reconnection logic and status management
- Tests — Verify auth, room management, and edge cases
Security Pack (¥1,480) includes /security-check for WebSocket security review — authentication gaps, missing rate limits, XSS vectors.
Myouga (@myougatheaxo) — Security-focused Claude Code engineer.
Top comments (0)