websocket-engineer by jeffallan/claude-skills
npx skills add https://github.com/jeffallan/claude-skills --skill websocket-engineernpx wscat -c ws://localhost:3000);确认在缺少/无效令牌时身份验证被拒绝、房间加入/离开事件以及消息传递根据上下文加载详细指导:
| 主题 | 参考 | 加载时机 |
|---|---|---|
| 协议 | references/protocol.md | WebSocket 握手、帧、ping/pong、关闭代码 |
| 扩展 | references/scaling.md |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 水平扩展、Redis 发布/订阅、粘性会话 |
| 模式 | references/patterns.md | 房间、命名空间、广播、确认 |
| 安全 | references/security.md | 身份验证、授权、速率限制、CORS |
| 替代方案 | references/alternatives.md | SSE、长轮询、何时选择 WebSocket |
import { createServer } from "http";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from "redis";
import jwt from "jsonwebtoken";
const httpServer = createServer();
const io = new Server(httpServer, {
cors: { origin: process.env.ALLOWED_ORIGIN, credentials: true },
pingTimeout: 20000,
pingInterval: 25000,
});
// 身份验证中间件 — 在连接建立前运行
io.use((socket, next) => {
const token = socket.handshake.auth.token;
if (!token) return next(new Error("Authentication required"));
try {
socket.data.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch {
next(new Error("Invalid token"));
}
});
// 用于水平扩展的 Redis 适配器
const pubClient = createClient({ url: process.env.REDIS_URL });
const subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);
io.adapter(createAdapter(pubClient, subClient));
io.on("connection", (socket) => {
const { userId } = socket.data.user;
console.log(`connected: ${userId} (${socket.id})`);
// 在线状态:标记用户在线
pubClient.hSet("presence", userId, socket.id);
socket.on("join-room", (roomId) => {
socket.join(roomId);
socket.to(roomId).emit("user-joined", { userId });
});
socket.on("message", ({ roomId, text }) => {
io.to(roomId).emit("message", { userId, text, ts: Date.now() });
});
socket.on("disconnect", () => {
pubClient.hDel("presence", userId);
console.log(`disconnected: ${userId}`);
});
});
httpServer.listen(3000);
import { io } from "socket.io-client";
const socket = io("wss://api.example.com", {
auth: { token: getAuthToken() },
reconnection: true,
reconnectionAttempts: 10,
reconnectionDelay: 1000, // 初始延迟(毫秒)
reconnectionDelayMax: 30000, // 上限 30 秒
randomizationFactor: 0.5, // 抖动以避免惊群效应
});
// 在断开连接时排队消息
let messageQueue = [];
socket.on("connect", () => {
console.log("connected:", socket.id);
// 清空排队的消息
messageQueue.forEach((msg) => socket.emit("message", msg));
messageQueue = [];
});
socket.on("disconnect", (reason) => {
console.warn("disconnected:", reason);
if (reason === "io server disconnect") socket.connect(); // 手动重连
});
socket.on("connect_error", (err) => {
console.error("connection error:", err.message);
});
function sendMessage(roomId, text) {
const msg = { roomId, text };
if (socket.connected) {
socket.emit("message", msg);
} else {
messageQueue.push(msg); // 缓冲直到重新连接
}
}
实现 WebSocket 功能时,请提供:
Socket.IO、ws、uWebSockets.js、Redis 适配器、粘性会话、nginx WebSocket 代理、基于 WebSocket 的 JWT、房间/命名空间、确认、二进制数据、压缩、心跳、背压、水平 Pod 自动扩缩
每周安装量
1.8K
仓库
GitHub 星标数
7.2K
首次出现
2026 年 1 月 20 日
安全审计
安装于
opencode1.5K
gemini-cli1.4K
codex1.4K
github-copilot1.3K
claude-code1.3K
cursor1.3K
npx wscat -c ws://localhost:3000); confirm auth rejection on missing/invalid tokens, room join/leave events, and message deliveryLoad detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Protocol | references/protocol.md | WebSocket handshake, frames, ping/pong, close codes |
| Scaling | references/scaling.md | Horizontal scaling, Redis pub/sub, sticky sessions |
| Patterns | references/patterns.md | Rooms, namespaces, broadcasting, acknowledgments |
| Security | references/security.md | Authentication, authorization, rate limiting, CORS |
| Alternatives | references/alternatives.md | SSE, long polling, when to choose WebSockets |
import { createServer } from "http";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from "redis";
import jwt from "jsonwebtoken";
const httpServer = createServer();
const io = new Server(httpServer, {
cors: { origin: process.env.ALLOWED_ORIGIN, credentials: true },
pingTimeout: 20000,
pingInterval: 25000,
});
// Authentication middleware — runs before connection is established
io.use((socket, next) => {
const token = socket.handshake.auth.token;
if (!token) return next(new Error("Authentication required"));
try {
socket.data.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch {
next(new Error("Invalid token"));
}
});
// Redis adapter for horizontal scaling
const pubClient = createClient({ url: process.env.REDIS_URL });
const subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);
io.adapter(createAdapter(pubClient, subClient));
io.on("connection", (socket) => {
const { userId } = socket.data.user;
console.log(`connected: ${userId} (${socket.id})`);
// Presence: mark user online
pubClient.hSet("presence", userId, socket.id);
socket.on("join-room", (roomId) => {
socket.join(roomId);
socket.to(roomId).emit("user-joined", { userId });
});
socket.on("message", ({ roomId, text }) => {
io.to(roomId).emit("message", { userId, text, ts: Date.now() });
});
socket.on("disconnect", () => {
pubClient.hDel("presence", userId);
console.log(`disconnected: ${userId}`);
});
});
httpServer.listen(3000);
import { io } from "socket.io-client";
const socket = io("wss://api.example.com", {
auth: { token: getAuthToken() },
reconnection: true,
reconnectionAttempts: 10,
reconnectionDelay: 1000, // initial delay (ms)
reconnectionDelayMax: 30000, // cap at 30 s
randomizationFactor: 0.5, // jitter to avoid thundering herd
});
// Queue messages while disconnected
let messageQueue = [];
socket.on("connect", () => {
console.log("connected:", socket.id);
// Flush queued messages
messageQueue.forEach((msg) => socket.emit("message", msg));
messageQueue = [];
});
socket.on("disconnect", (reason) => {
console.warn("disconnected:", reason);
if (reason === "io server disconnect") socket.connect(); // manual reconnect
});
socket.on("connect_error", (err) => {
console.error("connection error:", err.message);
});
function sendMessage(roomId, text) {
const msg = { roomId, text };
if (socket.connected) {
socket.emit("message", msg);
} else {
messageQueue.push(msg); // buffer until reconnected
}
}
When implementing WebSocket features, provide:
Socket.IO, ws, uWebSockets.js, Redis adapter, sticky sessions, nginx WebSocket proxy, JWT over WebSocket, rooms/namespaces, acknowledgments, binary data, compression, heartbeat, backpressure, horizontal pod autoscaling
Weekly Installs
1.8K
Repository
GitHub Stars
7.2K
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode1.5K
gemini-cli1.4K
codex1.4K
github-copilot1.3K
claude-code1.3K
cursor1.3K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装