Token导航 LogoToken导航TokenDH.com
待分类权限需确认github未标认证来源可访问许可证需确认审计异常

websockets-realtime实时网络套接字

Agent Skill

websockets-realtime 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

2,007

周安装

82

GitHub Stars

48

下载量

649
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:websockets-realtime(实时网络套接字)
来源仓库:https://github.com/travisjneuman/.claude
仓库路径:skills/websockets-realtime
安装命令:
npx skills add https://github.com/travisjneuman/.claude --skill websockets-realtime
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/travisjneuman/.claude --skill websockets-realtime

简介

websockets-realtime 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态进行整理。
  • 通过 npx skills add 命令安装,需结合来源仓库和 README 核验用法。
  • 安装前建议确认权限范围、维护状态及是否会触发联网或命令执行。
  • 当前功能描述与 travel-planner 高度相似,可能存在重复定义。

SKILL.md

name
websockets-realtime
description
Real-time communication with WebSockets, Server-Sent Events, and related technologies. Use when building chat, live updates, collaborative features, or any real-time functionality.

WebSockets & Real-Time

Comprehensive guide for building real-time applications.

Real-Time Technologies

Comparison

TechnologyDirectionUse Case
WebSocketBidirectionalChat, gaming, collaboration
Server-Sent EventsServer → ClientLive feeds, notifications
Long PollingSimulated bidirectionalFallback, simple updates
WebRTCPeer-to-peerVideo calls, file sharing

When to Use What

WEBSOCKETS:
✓ Chat applications
✓ Real-time collaboration
✓ Gaming
✓ Financial trading
✓ IoT dashboards
✓ Any bidirectional communication

SERVER-SENT EVENTS (SSE):
✓ Live feeds (news, sports)
✓ Notifications
✓ Progress updates
✓ Server-initiated updates only

LONG POLLING:
✓ Fallback when WebSocket unavailable
✓ Simple, infrequent updates
✓ Behind strict firewalls

WEBRTC:
✓ Video/audio calls
✓ Screen sharing
✓ Peer-to-peer file transfer

WebSocket Fundamentals

How WebSockets Work

HTTP Upgrade Handshake:
┌──────┐                      ┌──────┐
│Client│  GET /ws HTTP/1.1    │Server│
│      │  Upgrade: websocket  │      │
│      │ ──────────────────>  │      │
│      │                      │      │
│      │  HTTP/1.1 101        │      │
│      │  Switching Protocols │      │
│      │ <──────────────────  │      │
└──────┘                      └──────┘

After handshake:
┌──────┐                      ┌──────┐
│Client│ <═══════════════════>│Server│
│      │  Full-duplex TCP     │      │
│      │  Binary or text      │      │
└──────┘                      └──────┘

Client Implementation

// Basic WebSocket client
const ws = new WebSocket("wss://api.example.com/ws");

ws.onopen = () => {
  console.log("Connected");
  ws.send(JSON.stringify({ type: "subscribe", channel: "updates" }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log("Received:", data);
};

ws.onerror = (error) => {
  console.error("WebSocket error:", error);
};

ws.onclose = (event) => {
  console.log("Disconnected:", event.code, event.reason);
};

// Send message
ws.send(JSON.stringify({ type: "message", content: "Hello!" }));

// Close connection
ws.close(1000, "Normal closure");

Reconnection Logic

class ReconnectingWebSocket {
  private ws: WebSocket | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 10;
  private reconnectDelay = 1000;

  constructor(private url: string) {
    this.connect();
  }

  private connect() {
    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      console.log("Connected");
      this.reconnectAttempts = 0;
    };

    this.ws.onclose = (event) => {
      if (event.code !== 1000) {
        this.reconnect();
      }
    };

    this.ws.onerror = () => {
      this.ws?.close();
    };
  }

  private reconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error("Max reconnection attempts reached");
      return;
    }

    this.reconnectAttempts++;
    const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);

    console.log(
      `Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`,
    );

    setTimeout(() => this.connect(), delay);
  }

  send(data: unknown) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data));
    }
  }
}

Server Implementation (Node.js)

ws Library

import { WebSocketServer, WebSocket } from "ws";
import { createServer } from "http";

const server = createServer();
const wss = new WebSocketServer({ server });

// Track connected clients
const clients = new Set<WebSocket>();

wss.on("connection", (ws, request) => {
  console.log("Client connected");
  clients.add(ws);

  // Send welcome message
  ws.send(JSON.stringify({ type: "connected", clientCount: clients.size }));

  ws.on("message", (data) => {
    try {
      const message = JSON.parse(data.toString());
      handleMessage(ws, message);
    } catch (error) {
      ws.send(JSON.stringify({ type: "error", message: "Invalid JSON" }));
    }
  });

  ws.on("close", () => {
    clients.delete(ws);
    console.log("Client disconnected");
  });

  ws.on("error", (error) => {
    console.error("WebSocket error:", error);
  });

  // Heartbeat to detect stale connections
  ws.isAlive = true;
  ws.on("pong", () => {
    ws.isAlive = true;
  });
});

// Heartbeat interval
const heartbeatInterval = setInterval(() => {
  wss.clients.forEach((ws) => {
    if (!ws.isAlive) {
      return ws.terminate();
    }
    ws.isAlive = false;
    ws.ping();
  });
}, 30000);

wss.on("close", () => {
  clearInterval(heartbeatInterval);
});

function handleMessage(ws: WebSocket, message: any) {
  switch (message.type) {
    case "broadcast":
      broadcast(message.content);
      break;
    case "private":
      // Handle private messages
      break;
    default:
      ws.send(
        JSON.stringify({ type: "error", message: "Unknown message type" }),
      );
  }
}

function broadcast(content: any) {
  const message = JSON.stringify({ type: "broadcast", content });
  clients.forEach((client) => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(message);
    }
  });
}

server.listen(3000);

Socket.IO

import { Server } from "socket.io";
import { createServer } from "http";

const httpServer = createServer();
const io = new Server(httpServer, {
  cors: {
    origin: "https://example.com",
    methods: ["GET", "POST"],
  },
});

// Namespace for chat
const chat = io.of("/chat");

chat.on("connection", (socket) => {
  console.log("User connected:", socket.id);

  // Join room
  socket.on("join", (room: string) => {
    socket.join(room);
    socket.to(room).emit("user_joined", { userId: socket.id });
  });

  // Handle message
  socket.on("message", (data: { room: string; content: string }) => {
    chat.to(data.room).emit("message", {
      from: socket.id,
      content: data.content,
      timestamp: Date.now(),
    });
  });

  // Leave room
  socket.on("leave", (room: string) => {
    socket.leave(room);
    socket.to(room).emit("user_left", { userId: socket.id });
  });

  socket.on("disconnect", () => {
    console.log("User disconnected:", socket.id);
  });
});

// Authentication middleware
io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  if (validateToken(token)) {
    socket.data.user = decodeToken(token);
    next();
  } else {
    next(new Error("Authentication error"));
  }
});

httpServer.listen(3000);

Server-Sent Events (SSE)

Server Implementation

import express from "express";

const app = express();

app.get("/events", (req, res) => {
  // Set SSE headers
  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");

  // Send initial event
  res.write("event: connected\n");
  res.write('data: {"status": "connected"}\n\n');

  // Send periodic updates
  const interval = setInterval(() => {
    const data = JSON.stringify({
      timestamp: Date.now(),
      value: Math.random(),
    });
    res.write(`data: ${data}\n\n`);
  }, 1000);

  // Cleanup on disconnect
  req.on("close", () => {
    clearInterval(interval);
    res.end();
  });
});

app.listen(3000);

Client Implementation

const eventSource = new EventSource("/events");

eventSource.onopen = () => {
  console.log("SSE connection opened");
};

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log("Received:", data);
};

eventSource.addEventListener("connected", (event) => {
  console.log("Connected event:", event.data);
});

eventSource.onerror = (error) => {
  console.error("SSE error:", error);
  if (eventSource.readyState === EventSource.CLOSED) {
    // Reconnect logic if needed
  }
};

// Close connection
eventSource.close();

Message Protocols

JSON Message Format

// Define message types
interface BaseMessage {
  type: string;
  timestamp: number;
  id: string;
}

interface ChatMessage extends BaseMessage {
  type: "chat";
  room: string;
  content: string;
  sender: string;
}

interface PresenceMessage extends BaseMessage {
  type: "presence";
  status: "online" | "offline" | "away";
  userId: string;
}

interface ErrorMessage extends BaseMessage {
  type: "error";
  code: string;
  message: string;
}

type Message = ChatMessage | PresenceMessage | ErrorMessage;

// Type-safe message handling
function handleMessage(data: string) {
  const message: Message = JSON.parse(data);

  switch (message.type) {
    case "chat":
      displayChatMessage(message);
      break;
    case "presence":
      updateUserPresence(message);
      break;
    case "error":
      handleError(message);
      break;
  }
}

Binary Protocols

// For high-performance needs, use binary formats

// MessagePack
import { encode, decode } from "@msgpack/msgpack";

const encoded = encode({ type: "position", x: 100, y: 200 });
ws.send(encoded);

ws.onmessage = (event) => {
  const data = decode(event.data);
};

// Protocol Buffers
// Define schema in .proto file, generate types
// Smaller messages, faster serialization

Scaling WebSockets

Architecture

                    Load Balancer
                   (Sticky Sessions)
                         │
        ┌────────────────┼────────────────┐
        │                │                │
        ▼                ▼                ▼
   ┌─────────┐      ┌─────────┐      ┌─────────┐
   │ Server 1│      │ Server 2│      │ Server 3│
   │ (Node)  │      │ (Node)  │      │ (Node)  │
   └────┬────┘      └────┬────┘      └────┬────┘
        │                │                │
        └────────────────┼────────────────┘
                         │
                    ┌─────────┐
                    │  Redis  │
                    │ Pub/Sub │
                    └─────────┘

Redis Pub/Sub for Cross-Server Messages

import Redis from "ioredis";
import { WebSocketServer } from "ws";

const pub = new Redis();
const sub = new Redis();

const wss = new WebSocketServer({ port: 3000 });

// Subscribe to channel
sub.subscribe("broadcast");

// Forward Redis messages to local clients
sub.on("message", (channel, message) => {
  wss.clients.forEach((client) => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(message);
    }
  });
});

// Publish messages to Redis
function broadcast(message: object) {
  pub.publish("broadcast", JSON.stringify(message));
}

// Receive from WebSocket, publish to Redis
wss.on("connection", (ws) => {
  ws.on("message", (data) => {
    broadcast(JSON.parse(data.toString()));
  });
});

Socket.IO with Redis Adapter

import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from "redis";

const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();

await Promise.all([pubClient.connect(), subClient.connect()]);

const io = new Server();
io.adapter(createAdapter(pubClient, subClient));

// Now messages are automatically synchronized across servers
io.emit("notification", { message: "Hello all servers!" });

React Integration

Custom Hook

import { useEffect, useRef, useState, useCallback } from 'react';

interface UseWebSocketOptions {
  url: string;
  onMessage?: (data: any) => void;
  reconnect?: boolean;
}

export function useWebSocket(options: UseWebSocketOptions) {
  const { url, onMessage, reconnect = true } = options;
  const wsRef = useRef<WebSocket | null>(null);
  const [isConnected, setIsConnected] = useState(false);
  const [lastMessage, setLastMessage] = useState<any>(null);

  const connect = useCallback(() => {
    const ws = new WebSocket(url);

    ws.onopen = () => setIsConnected(true);

    ws.onmessage = (event) => {
      const data = JSON.parse(event.data);
      setLastMessage(data);
      onMessage?.(data);
    };

    ws.onclose = () => {
      setIsConnected(false);
      if (reconnect) {
        setTimeout(connect, 3000);
      }
    };

    wsRef.current = ws;
  }, [url, onMessage, reconnect]);

  useEffect(() => {
    connect();
    return () => {
      wsRef.current?.close();
    };
  }, [connect]);

  const send = useCallback((data: any) => {
    if (wsRef.current?.readyState === WebSocket.OPEN) {
      wsRef.current.send(JSON.stringify(data));
    }
  }, []);

  return { isConnected, lastMessage, send };
}

// Usage
function ChatComponent() {
  const { isConnected, lastMessage, send } = useWebSocket({
    url: 'wss://api.example.com/chat',
    onMessage: (data) => {
      console.log('New message:', data);
    },
  });

  return (
    <div>
      <span>Status: {isConnected ? 'Connected' : 'Disconnected'}</span>
      <button onClick={() => send({ type: 'message', content: 'Hello!' })}>
        Send
      </button>
    </div>
  );
}

Socket.IO Client

import { io, Socket } from 'socket.io-client';
import { createContext, useContext, useEffect, useState } from 'react';

const SocketContext = createContext<Socket | null>(null);

export function SocketProvider({ children }: { children: React.ReactNode }) {
  const [socket, setSocket] = useState<Socket | null>(null);

  useEffect(() => {
    const newSocket = io('https://api.example.com', {
      auth: { token: getAuthToken() },
    });

    setSocket(newSocket);

    return () => {
      newSocket.close();
    };
  }, []);

  return (
    <SocketContext.Provider value={socket}>{children}</SocketContext.Provider>
  );
}

export function useSocket() {
  const socket = useContext(SocketContext);
  if (!socket) {
    throw new Error('useSocket must be used within SocketProvider');
  }
  return socket;
}

// Usage
function ChatRoom({ roomId }: { roomId: string }) {
  const socket = useSocket();
  const [messages, setMessages] = useState<Message[]>([]);

  useEffect(() => {
    socket.emit('join', roomId);

    socket.on('message', (message: Message) => {
      setMessages((prev) => [...prev, message]);
    });

    return () => {
      socket.emit('leave', roomId);
      socket.off('message');
    };
  }, [socket, roomId]);

  const sendMessage = (content: string) => {
    socket.emit('message', { room: roomId, content });
  };

  return (/* render messages */);
}

Security

Authentication

// Token-based authentication
const ws = new WebSocket("wss://api.example.com/ws");

ws.onopen = () => {
  // Send auth message immediately
  ws.send(
    JSON.stringify({
      type: "auth",
      token: localStorage.getItem("token"),
    }),
  );
};

// Server-side validation
wss.on("connection", (ws, request) => {
  let authenticated = false;
  const authTimeout = setTimeout(() => {
    if (!authenticated) {
      ws.close(4001, "Authentication timeout");
    }
  }, 5000);

  ws.on("message", (data) => {
    const message = JSON.parse(data.toString());

    if (message.type === "auth") {
      if (validateToken(message.token)) {
        authenticated = true;
        clearTimeout(authTimeout);
        ws.send(JSON.stringify({ type: "auth_success" }));
      } else {
        ws.close(4002, "Invalid token");
      }
    } else if (!authenticated) {
      ws.close(4003, "Not authenticated");
    }
  });
});

Rate Limiting

const rateLimits = new Map<WebSocket, { count: number; timestamp: number }>();

function checkRateLimit(ws: WebSocket): boolean {
  const now = Date.now();
  const limit = rateLimits.get(ws);

  if (!limit || now - limit.timestamp > 1000) {
    rateLimits.set(ws, { count: 1, timestamp: now });
    return true;
  }

  if (limit.count >= 10) {
    // 10 messages per second
    return false;
  }

  limit.count++;
  return true;
}

ws.on("message", (data) => {
  if (!checkRateLimit(ws)) {
    ws.send(JSON.stringify({ type: "error", message: "Rate limit exceeded" }));
    return;
  }
  // Process message
});

Best Practices

DO:

  • Use WSS (WebSocket Secure) in production
  • Implement heartbeat/ping-pong
  • Handle reconnection gracefully
  • Authenticate connections
  • Validate all incoming messages
  • Use message IDs for acknowledgment
  • Implement backpressure handling
  • Monitor connection health

DON'T:

  • Trust client data without validation
  • Send sensitive data without encryption
  • Keep connections open indefinitely
  • Ignore disconnection handling
  • Block the message handler
  • Send unbounded data
  • Forget about horizontal scaling

Troubleshooting

Common Issues

ProblemCauseSolution
Connection dropsIdle timeoutImplement heartbeat
Messages lostNo acknowledgmentAdd message IDs + acks
High latencyLarge messagesUse binary, compress
Memory leakUnclosed connectionsProper cleanup
Cross-origin blockedMissing CORSConfigure server CORS

Debug Logging

// Development logging
if (process.env.NODE_ENV === "development") {
  ws.on("message", (data) => {
    console.log("← Received:", JSON.parse(data.toString()));
  });

  const originalSend = ws.send.bind(ws);
  ws.send = (data: string) => {
    console.log("→ Sending:", JSON.parse(data));
    originalSend(data);
  };
}

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

32.35%
按下载量换算210

Claude

31.64%
按下载量换算205

Cursor

17.72%
按下载量换算115

Gemini CLI

9.65%
按下载量换算63

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

可疑

权限和风险

权限需确认

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills