
Websocket Implementation
- 600 installs
- 305 repo stars
- Updated March 4, 2026
- aj-geddes/useful-ai-prompts
websocket-implementation is an agent skill that provides copy-paste WebSocket and Socket.IO client and server patterns with reconnect, auth handshakes, offline queues, and Redis scaling for developers shipping live SaaS
About
websocket-implementation is an agent skill from aj-geddes/useful-ai-prompts for engineers adding real-time chat, notifications, dashboards, or collaborative editing. It bundles five reference guides covering a Node.js Socket.IO server, browser WebSocket client, Python aiohttp server, message-type protocols, and Redis horizontal scaling with @socket.io/redis-adapter. The quick-start server configures reconnection with reconnectionAttempts set to 5, reconnectionDelay 1000 ms, and Redis adapter wiring for multi-node deployments. Browser client examples track reconnectAttempts, messageQueue buffering while offline, and isAuthenticated handshake state. Best-practice checklists cover room management, message acknowledgment, rate limiting, and connection cleanup. Developers reach for websocket-implementation when scaffolding bidirectional transport instead of inventing reconnect and auth edge cases from scratch for each feature, especially in SaaS products that must survive flaky mobile networks and horizontal scale-out. Reference files split server, browser, Python, protocol, and Redis scaling concerns so agents paste only the slice needed.
- Reusable WebSocketClient class with configurable max reconnect attempts and backoff delay
- Socket.IO connect/disconnect/error and connect_error listeners with queued flush on reconnect
- Auth emit flow with success callback and isAuthenticated gate before sensitive events
- Listener map and on() registration pattern for extensible event routing
- Message queue processing when the socket comes back online
Websocket Implementation by the numbers
- 600 all-time installs (skills.sh)
- Ranked #656 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aj-geddes/useful-ai-prompts --skill websocket-implementationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 600 |
|---|---|
| repo stars | ★ 305 |
| Security audit | 2 / 3 scanners passed |
| Last updated | March 4, 2026 |
| Repository | aj-geddes/useful-ai-prompts ↗ |
How do you implement production WebSocket reconnect logic?
Give your coding agent copy-paste WebSocket and Socket.IO client patterns with reconnect, auth handshakes, and offline message queues for live SaaS features.
Who is it for?
Full-stack developers adding resilient real-time messaging to SaaS apps with Socket.IO, auth handshakes, and Redis-backed scaling.
Skip if: Projects that only need occasional REST polling or teams standardized on a managed pub/sub service without custom socket code.
When should I use this skill?
A developer asks for WebSocket, Socket.IO, live notifications, chat transport, or Redis-scaled socket clusters.
What you get
Socket.IO server and browser client modules, Redis adapter scaling setup, and message routing protocol references
- Socket.IO server module
- Browser client with reconnect queue
- Redis adapter scaling config
By the numbers
- Includes 5 reference implementation guides in the references/ directory
- Default Socket.IO client/server examples set reconnectionAttempts to 5
Files
WebSocket Implementation
Table of Contents
Overview
Build scalable WebSocket systems for real-time communication with proper connection management, message routing, error handling, and horizontal scaling support.
When to Use
- Building real-time chat and messaging
- Implementing live notifications
- Creating collaborative editing tools
- Broadcasting live data updates
- Building real-time dashboards
- Streaming events to clients
- Live multiplayer games
Quick Start
Minimal working example:
const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const redis = require("redis");
const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
cors: { origin: "*" },
transports: ["websocket", "polling"],
reconnection: true,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
reconnectionAttempts: 5,
});
// Redis adapter for horizontal scaling
const redisClient = redis.createClient();
const { createAdapter } = require("@socket.io/redis-adapter");
io.adapter(createAdapter(redisClient, redisClient.duplicate()));
// Connection management
const connectedUsers = new Map();
// ... (see reference guides for full implementation)Reference Guides
Detailed implementations in the references/ directory:
| Guide | Contents |
|---|---|
| Node.js WebSocket Server (Socket.IO) | Node.js WebSocket Server (Socket.IO) |
| Browser WebSocket Client | Browser WebSocket Client |
| Python WebSocket Server (aiohttp) | Python WebSocket Server (aiohttp) |
| Message Types and Protocols | Message Types and Protocols |
| Scaling with Redis | Scaling with Redis |
Best Practices
✅ DO
- Implement proper authentication
- Handle reconnection gracefully
- Manage rooms/channels effectively
- Persist messages appropriately
- Monitor active connections
- Implement presence features
- Use Redis for scaling
- Add message acknowledgment
- Implement rate limiting
- Handle errors properly
❌ DON'T
- Send unencrypted sensitive data
- Keep unlimited message history in memory
- Allow arbitrary room/channel creation
- Forget to clean up disconnected connections
- Send large messages frequently
- Ignore network failures
- Store passwords in messages
- Skip authentication/authorization
- Create unbounded growth of connections
- Ignore scalability from day one
Browser WebSocket Client
Browser WebSocket Client
class WebSocketClient {
constructor(url, options = {}) {
this.url = url;
this.socket = null;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
this.reconnectDelay = options.reconnectDelay || 1000;
this.listeners = new Map();
this.messageQueue = [];
this.isAuthenticated = false;
this.connect();
}
connect() {
this.socket = io(this.url, {
reconnection: true,
reconnectionDelay: this.reconnectDelay,
reconnectionAttempts: this.maxReconnectAttempts,
});
this.socket.on("connect", () => {
console.log("Connected to server");
this.reconnectAttempts = 0;
this.processMessageQueue();
});
this.socket.on("disconnect", () => {
console.log("Disconnected from server");
});
this.socket.on("error", (error) => {
console.error("Socket error:", error);
this.emit("error", error);
});
this.socket.on("connect_error", (error) => {
console.error("Connection error:", error);
});
}
authenticate(userData) {
this.socket.emit("auth", userData, (response) => {
if (response.success) {
this.isAuthenticated = true;
this.emit("authenticated");
}
});
}
on(event, callback) {
this.socket.on(event, callback);
if (!this.listeners.has(event)) {
this.listeners.set(event, []);
}
this.listeners.get(event).push(callback);
}
emit(event, data, callback) {
if (!this.socket.connected) {
this.messageQueue.push({ event, data, callback });
return;
}
this.socket.emit(event, data, callback);
}
processMessageQueue() {
while (this.messageQueue.length > 0) {
const { event, data, callback } = this.messageQueue.shift();
this.socket.emit(event, data, callback);
}
}
joinRoom(roomId) {
this.emit("room:join", roomId);
}
leaveRoom(roomId) {
this.emit("room:leave", roomId);
}
sendMessage(roomId, text) {
this.emit("chat:message", { roomId, text });
}
setTypingIndicator(roomId, isTyping) {
if (isTyping) {
this.emit("typing:start", roomId);
} else {
this.emit("typing:stop", roomId);
}
}
disconnect() {
this.socket.disconnect();
}
}
// Usage
const client = new WebSocketClient("http://localhost:3000");
client.on("chat:message", (message) => {
console.log("Received message:", message);
displayMessage(message);
});
client.on("typing:indicator", (data) => {
updateTypingIndicator(data);
});
client.on("user:online", (user) => {
updateUserStatus(user.userId, "online");
});
client.authenticate({ id: "user123", username: "john" });
client.joinRoom("room1");
client.sendMessage("room1", "Hello everyone!");Message Types and Protocols
Message Types and Protocols
// Authentication
{
"type": "auth",
"userId": "user123",
"token": "jwt_token_here"
}
// Chat Message
{
"type": "message",
"roomId": "room123",
"text": "Hello everyone!",
"timestamp": "2025-01-15T10:30:00Z"
}
// Typing Indicator
{
"type": "typing",
"roomId": "room123",
"isTyping": true
}
// Presence
{
"type": "presence",
"status": "online|away|offline"
}
// Notification
{
"type": "notification",
"title": "New message",
"body": "You have a new message",
"data": {}
}Node.js WebSocket Server (Socket.IO)
Node.js WebSocket Server (Socket.IO)
const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const redis = require("redis");
const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
cors: { origin: "*" },
transports: ["websocket", "polling"],
reconnection: true,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
reconnectionAttempts: 5,
});
// Redis adapter for horizontal scaling
const redisClient = redis.createClient();
const { createAdapter } = require("@socket.io/redis-adapter");
io.adapter(createAdapter(redisClient, redisClient.duplicate()));
// Connection management
const connectedUsers = new Map();
io.on("connection", (socket) => {
console.log(`User connected: ${socket.id}`);
// Store user connection
socket.on("auth", (userData) => {
connectedUsers.set(socket.id, {
userId: userData.id,
username: userData.username,
socketId: socket.id,
connectedAt: new Date(),
});
// Join user-specific room
socket.join(`user:${userData.id}`);
socket.join("authenticated_users");
// Notify others user is online
io.to("authenticated_users").emit("user:online", {
userId: userData.id,
username: userData.username,
timestamp: new Date(),
});
console.log(`User authenticated: ${userData.username}`);
});
// Chat messaging
socket.on("chat:message", (message) => {
const user = connectedUsers.get(socket.id);
if (!user) {
socket.emit("error", { message: "Not authenticated" });
return;
}
const chatMessage = {
id: `msg_${Date.now()}`,
senderId: user.userId,
senderName: user.username,
text: message.text,
roomId: message.roomId,
timestamp: new Date(),
status: "delivered",
};
// Save to database
Message.create(chatMessage);
// Broadcast to room
io.to(`room:${message.roomId}`).emit("chat:message", chatMessage);
// Update message status
setTimeout(() => {
socket.emit("chat:message:ack", {
messageId: chatMessage.id,
status: "read",
});
}, 100);
});
// Room management
socket.on("room:join", (roomId) => {
socket.join(`room:${roomId}`);
const user = connectedUsers.get(socket.id);
io.to(`room:${roomId}`).emit("room:user:joined", {
userId: user.userId,
username: user.username,
timestamp: new Date(),
});
});
socket.on("room:leave", (roomId) => {
socket.leave(`room:${roomId}`);
const user = connectedUsers.get(socket.id);
io.to(`room:${roomId}`).emit("room:user:left", {
userId: user.userId,
timestamp: new Date(),
});
});
// Typing indicator
socket.on("typing:start", (roomId) => {
const user = connectedUsers.get(socket.id);
io.to(`room:${roomId}`).emit("typing:indicator", {
userId: user.userId,
username: user.username,
isTyping: true,
});
});
socket.on("typing:stop", (roomId) => {
const user = connectedUsers.get(socket.id);
io.to(`room:${roomId}`).emit("typing:indicator", {
userId: user.userId,
isTyping: false,
});
});
// Handle disconnection
socket.on("disconnect", () => {
const user = connectedUsers.get(socket.id);
if (user) {
connectedUsers.delete(socket.id);
io.to("authenticated_users").emit("user:offline", {
userId: user.userId,
timestamp: new Date(),
});
console.log(`User disconnected: ${user.username}`);
}
});
// Error handling
socket.on("error", (error) => {
console.error(`Socket error: ${error}`);
socket.emit("error", { message: "An error occurred" });
});
});
// Server methods
const broadcastUserUpdate = (userId, data) => {
io.to(`user:${userId}`).emit("user:update", data);
};
const notifyRoom = (roomId, event, data) => {
io.to(`room:${roomId}`).emit(event, data);
};
const sendDirectMessage = (userId, event, data) => {
io.to(`user:${userId}`).emit(event, data);
};
server.listen(3000, () => {
console.log("WebSocket server listening on port 3000");
});Python WebSocket Server (aiohttp)
Python WebSocket Server (aiohttp)
from aiohttp import web
import aiohttp
import json
from datetime import datetime
from typing import Set
class WebSocketServer:
def __init__(self):
self.app = web.Application()
self.rooms = {}
self.users = {}
self.setup_routes()
def setup_routes(self):
self.app.router.add_get('/ws', self.websocket_handler)
self.app.router.add_post('/api/message', self.send_message_api)
async def websocket_handler(self, request):
ws = web.WebSocketResponse()
await ws.prepare(request)
user_id = None
room_id = None
async for msg in ws.iter_any():
if isinstance(msg, aiohttp.WSMessage):
data = json.loads(msg.data)
event_type = data.get('type')
try:
if event_type == 'auth':
user_id = data.get('userId')
self.users[user_id] = ws
await ws.send_json({
'type': 'authenticated',
'timestamp': datetime.now().isoformat()
})
elif event_type == 'join_room':
room_id = data.get('roomId')
if room_id not in self.rooms:
self.rooms[room_id] = set()
self.rooms[room_id].add(user_id)
# Notify others
await self.broadcast_to_room(room_id, {
'type': 'user_joined',
'userId': user_id,
'timestamp': datetime.now().isoformat()
}, exclude=user_id)
elif event_type == 'message':
message = {
'id': f'msg_{datetime.now().timestamp()}',
'userId': user_id,
'text': data.get('text'),
'roomId': room_id,
'timestamp': datetime.now().isoformat()
}
# Save to database
await self.save_message(message)
# Broadcast to room
await self.broadcast_to_room(room_id, message)
elif event_type == 'leave_room':
if room_id in self.rooms:
self.rooms[room_id].discard(user_id)
except Exception as error:
await ws.send_json({
'type': 'error',
'message': str(error)
})
# Cleanup on disconnect
if user_id:
del self.users[user_id]
if room_id and user_id:
if room_id in self.rooms:
self.rooms[room_id].discard(user_id)
return ws
async def broadcast_to_room(self, room_id, message, exclude=None):
if room_id not in self.rooms:
return
for user_id in self.rooms[room_id]:
if user_id != exclude and user_id in self.users:
try:
await self.users[user_id].send_json(message)
except Exception as error:
print(f'Error sending message: {error}')
async def save_message(self, message):
# Save to database
pass
async def send_message_api(self, request):
data = await request.json()
room_id = data.get('roomId')
await self.broadcast_to_room(room_id, {
'type': 'message',
'text': data.get('text'),
'timestamp': datetime.now().isoformat()
})
return web.json_response({'sent': True})
def create_app():
server = WebSocketServer()
return server.app
if __name__ == '__main__':
app = create_app()
web.run_app(app, port=3000)Scaling with Redis
Scaling with Redis
const redis = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");
const { createClient } = require("redis");
const pubClient = createClient({ host: "redis", port: 6379 });
const subClient = pubClient.duplicate();
io.adapter(createAdapter(pubClient, subClient));
// Publish to multiple servers
io.emit("user:action", { userId: 123, action: "login" });
// Subscribe to events from other servers
redisClient.subscribe("notifications", (message) => {
const notification = JSON.parse(message);
io.to(`user:${notification.userId}`).emit("notification", notification);
});#!/bin/bash
# validate-api.sh - Validate API specification
# Usage: ./validate-api.sh <openapi_spec>
set -euo pipefail
SPEC_FILE="${{1:?Usage: $0 <openapi_spec>}}"
echo "Validating API spec: $SPEC_FILE"
# TODO: Add API validation
# - Validate OpenAPI/Swagger syntax
# - Check endpoint naming conventions
# - Verify response schemas
# - Check for required headers
# - Validate authentication definitions
echo "API validation complete."
# API Endpoint Scaffold
# TODO: Customize for your API framework
openapi: "3.0.3"
info:
title: "API Service"
version: "1.0.0"
paths:
/api/v1/resource:
get:
summary: "List resources"
# TODO: Define parameters and responses
responses:
"200":
description: "Success"
post:
summary: "Create resource"
# TODO: Define request body and responses
responses:
"201":
description: "Created"
Related skills
How it compares
Use websocket-implementation for self-hosted Socket.IO patterns; prefer managed realtime services when ops wants zero socket infrastructure.
FAQ
What stacks does websocket-implementation cover?
websocket-implementation includes five reference guides for a Node.js Socket.IO server, browser WebSocket client, Python aiohttp server, message protocols, and Redis scaling with @socket.io/redis-adapter.
How does websocket-implementation handle disconnects?
websocket-implementation patterns default to 5 reconnectionAttempts, configurable reconnectDelay, an offline messageQueue while disconnected, and isAuthenticated tracking so clients replay queued messages after a successful auth handshake.
Is Websocket Implementation safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.