Token导航 LogoToken导航TokenDH.com
前端设计操作浏览器github未标认证来源可访问clear审计异常

real-time-features实时功能

Agent Skill

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

总安装

906

周安装

37

GitHub Stars

公开资料未说明

下载量

290
CodexClaudeCursorGemini CLI

安装说明

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

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

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

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/eddiebe147/claude-settings --skill real-time-features

简介

用于前端功能的实时更新与特性管理。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

  • 支持动态加载组件和用户界面的即时调整。
  • 可协助集成第三方库并监控功能稳定性。
  • 部署变更前应在测试环境充分验证兼容性。
  • real-time-features 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Real-Time Features

Overview

Implement real-time bidirectional communication between clients and servers for instant data synchronization and live updates.

When to Use

  • Chat and messaging applications
  • Live dashboards and analytics
  • Collaborative editing (Google Docs-style)
  • Real-time notifications
  • Live sports scores or stock tickers
  • Multiplayer games
  • Live auctions or bidding systems
  • IoT device monitoring
  • Real-time location tracking

Technologies Comparison

TechnologyDirectionUse CaseBrowser Support
WebSocketsBidirectionalChat, gaming, collaborationExcellent
SSEServer → ClientLive updates, notificationsGood (no IE)
Long PollingRequest/ResponseFallback, simple updatesUniversal
WebRTCPeer-to-peerVideo/audio streamingGood

Implementation Examples

1. WebSocket Server (Node.js)

// server.ts
import WebSocket, { WebSocketServer } from 'ws';
import { createServer } from 'http';

interface Message {
  type: 'join' | 'message' | 'leave' | 'typing';
  userId: string;
  username: string;
  content?: string;
  timestamp: number;
}

interface Client {
  ws: WebSocket;
  userId: string;
  username: string;
  roomId: string;
}

class ChatServer {
  private wss: WebSocketServer;
  private clients: Map<string, Client> = new Map();
  private rooms: Map<string, Set<string>> = new Map();

  constructor(port: number) {
    const server = createServer();
    this.wss = new WebSocketServer({ server });

    this.wss.on('connection', this.handleConnection.bind(this));

    server.listen(port, () => {
      console.log(`WebSocket server running on port ${port}`);
    });

    // Heartbeat to detect disconnections
    this.startHeartbeat();
  }

  private handleConnection(ws: WebSocket): void {
    const clientId = this.generateId();

    console.log(`New connection: ${clientId}`);

    ws.on('message', (data: string) => {
      try {
        const message: Message = JSON.parse(data.toString());
        this.handleMessage(clientId, message, ws);
      } catch (error) {
        console.error('Invalid message format:', error);
      }
    });

    ws.on('close', () => {
      this.handleDisconnect(clientId);
    });

    ws.on('error', (error) => {
      console.error(`WebSocket error for ${clientId}:`, error);
    });

    // Keep connection alive
    (ws as any).isAlive = true;
    ws.on('pong', () => {
      (ws as any).isAlive = true;
    });
  }

  private handleMessage(
    clientId: string,
    message: Message,
    ws: WebSocket
  ): void {
    switch (message.type) {
      case 'join':
        this.handleJoin(clientId, message, ws);
        break;

      case 'message':
        this.broadcastToRoom(clientId, message);
        break;

      case 'typing':
        this.broadcastToRoom(clientId, message, [clientId]);
        break;

      case 'leave':
        this.handleDisconnect(clientId);
        break;
    }
  }

  private handleJoin(
    clientId: string,
    message: Message,
    ws: WebSocket
  ): void {
    const client: Client = {
      ws,
      userId: message.userId,
      username: message.username,
      roomId: 'general' // Could be dynamic
    };

    this.clients.set(clientId, client);

    // Add to room
    if (!this.rooms.has(client.roomId)) {
      this.rooms.set(client.roomId, new Set());
    }
    this.rooms.get(client.roomId)!.add(clientId);

    // Notify room
    this.broadcastToRoom(clientId, {
      type: 'join',
      userId: message.userId,
      username: message.username,
      timestamp: Date.now()
    });

    // Send room state to new user
    this.sendRoomState(clientId);
  }

  private broadcastToRoom(
    senderId: string,
    message: Message,
    exclude: string[] = []
  ): void {
    const sender = this.clients.get(senderId);
    if (!sender) return;

    const roomClients = this.rooms.get(sender.roomId);
    if (!roomClients) return;

    const payload = JSON.stringify(message);

    roomClients.forEach(clientId => {
      if (!exclude.includes(clientId)) {
        const client = this.clients.get(clientId);
        if (client && client.ws.readyState === WebSocket.OPEN) {
          client.ws.send(payload);
        }
      }
    });
  }

  private sendRoomState(clientId: string): void {
    const client = this.clients.get(clientId);
    if (!client) return;

    const roomClients = this.rooms.get(client.roomId);
    if (!roomClients) return;

    const users = Array.from(roomClients)
      .map(id => this.clients.get(id))
      .filter(c => c && c.userId !== client.userId)
      .map(c => ({ userId: c!.userId, username: c!.username }));

    client.ws.send(JSON.stringify({
      type: 'room_state',
      users,
      timestamp: Date.now()
    }));
  }

  private handleDisconnect(clientId: string): void {
    const client = this.clients.get(clientId);
    if (!client) return;

    // Remove from room
    const roomClients = this.rooms.get(client.roomId);
    if (roomClients) {
      roomClients.delete(clientId);

      // Notify others
      this.broadcastToRoom(clientId, {
        type: 'leave',
        userId: client.userId,
        username: client.username,
        timestamp: Date.now()
      });
    }

    this.clients.delete(clientId);
    console.log(`Client disconnected: ${clientId}`);
  }

  private startHeartbeat(): void {
    setInterval(() => {
      this.wss.clients.forEach((ws: any) => {
        if (ws.isAlive === false) {
          return ws.terminate();
        }
        ws.isAlive = false;
        ws.ping();
      });
    }, 30000);
  }

  private generateId(): string {
    return Math.random().toString(36).substr(2, 9);
  }
}

// Start server
new ChatServer(8080);

2. WebSocket Client (React)

// useWebSocket.ts
import { useEffect, useRef, useState, useCallback } from 'react';

interface UseWebSocketOptions {
  url: string;
  onMessage?: (data: any) => void;
  onOpen?: () => void;
  onClose?: () => void;
  onError?: (error: Event) => void;
  reconnectAttempts?: number;
  reconnectInterval?: number;
}

export const useWebSocket = (options: UseWebSocketOptions) => {
  const {
    url,
    onMessage,
    onOpen,
    onClose,
    onError,
    reconnectAttempts = 5,
    reconnectInterval = 3000
  } = options;

  const [isConnected, setIsConnected] = useState(false);
  const [connectionStatus, setConnectionStatus] = useState<
    'connecting' | 'connected' | 'disconnected' | 'error'
  >('connecting');

  const wsRef = useRef<WebSocket | null>(null);
  const reconnectCountRef = useRef(0);
  const reconnectTimeoutRef = useRef<NodeJS.Timeout>();

  const connect = useCallback(() => {
    try {
      setConnectionStatus('connecting');
      const ws = new WebSocket(url);

      ws.onopen = () => {
        console.log('WebSocket connected');
        setIsConnected(true);
        setConnectionStatus('connected');
        reconnectCountRef.current = 0;
        onOpen?.();
      };

      ws.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data);
          onMessage?.(data);
        } catch (error) {
          console.error('Failed to parse message:', error);
        }
      };

      ws.onerror = (error) => {
        console.error('WebSocket error:', error);
        setConnectionStatus('error');
        onError?.(error);
      };

      ws.onclose = () => {
        console.log('WebSocket disconnected');
        setIsConnected(false);
        setConnectionStatus('disconnected');
        onClose?.();

        // Attempt reconnection
        if (reconnectCountRef.current < reconnectAttempts) {
          reconnectCountRef.current++;
          console.log(
            `Reconnecting... (${reconnectCountRef.current}/${reconnectAttempts})`
          );
          reconnectTimeoutRef.current = setTimeout(() => {
            connect();
          }, reconnectInterval);
        }
      };

      wsRef.current = ws;
    } catch (error) {
      console.error('Failed to connect:', error);
      setConnectionStatus('error');
    }
  }, [url, onMessage, onOpen, onClose, onError, reconnectAttempts, reconnectInterval]);

  const disconnect = useCallback(() => {
    if (reconnectTimeoutRef.current) {
      clearTimeout(reconnectTimeoutRef.current);
    }
    wsRef.current?.close();
    wsRef.current = null;
  }, []);

  const send = useCallback((data: any) => {
    if (wsRef.current?.readyState === WebSocket.OPEN) {
      wsRef.current.send(JSON.stringify(data));
    } else {
      console.warn('WebSocket is not connected');
    }
  }, []);

  useEffect(() => {
    connect();
    return () => {
      disconnect();
    };
  }, [connect, disconnect]);

  return {
    isConnected,
    connectionStatus,
    send,
    disconnect,
    reconnect: connect
  };
};

// Usage in component
const ChatComponent: React.FC = () => {
  const [messages, setMessages] = useState<any[]>([]);

  const { isConnected, send } = useWebSocket({
    url: 'ws://localhost:8080',
    onMessage: (data) => {
      if (data.type === 'message') {
        setMessages(prev => [...prev, data]);
      }
    },
    onOpen: () => {
      send({
        type: 'join',
        userId: 'user123',
        username: 'John Doe',
        timestamp: Date.now()
      });
    }
  });

  const sendMessage = (content: string) => {
    send({
      type: 'message',
      userId: 'user123',
      username: 'John Doe',
      content,
      timestamp: Date.now()
    });
  };

  return (
    <div>
      <div>Status: {isConnected ? 'Connected' : 'Disconnected'}</div>
      <div>
        {messages.map((msg, i) => (
          <div key={i}>{msg.username}: {msg.content}</div>
        ))}
      </div>
    </div>
  );
};

3. Server-Sent Events (SSE)

// server.ts - SSE endpoint
import express from 'express';

const app = express();

interface Client {
  id: string;
  res: express.Response;
}

class SSEManager {
  private clients: Client[] = [];

  addClient(id: string, res: express.Response): void {
    // Set SSE headers
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');
    res.setHeader('Access-Control-Allow-Origin', '*');

    this.clients.push({ id, res });

    // Send initial connection event
    this.sendToClient(id, {
      type: 'connected',
      clientId: id,
      timestamp: Date.now()
    });

    console.log(`Client ${id} connected. Total: ${this.clients.length}`);
  }

  removeClient(id: string): void {
    this.clients = this.clients.filter(client => client.id !== id);
    console.log(`Client ${id} disconnected. Total: ${this.clients.length}`);
  }

  sendToClient(id: string, data: any): void {
    const client = this.clients.find(c => c.id === id);
    if (client) {
      client.res.write(`data: ${JSON.stringify(data)}\n\n`);
    }
  }

  broadcast(data: any, excludeId?: string): void {
    const message = `data: ${JSON.stringify(data)}\n\n`;
    this.clients.forEach(client => {
      if (client.id !== excludeId) {
        client.res.write(message);
      }
    });
  }

  sendEvent(event: string, data: any): void {
    const message = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
    this.clients.forEach(client => {
      client.res.write(message);
    });
  }
}

const sseManager = new SSEManager();

app.get('/events', (req, res) => {
  const clientId = Math.random().toString(36).substr(2, 9);

  sseManager.addClient(clientId, res);

  req.on('close', () => {
    sseManager.removeClient(clientId);
  });
});

// Simulate real-time updates
setInterval(() => {
  sseManager.broadcast({
    type: 'update',
    value: Math.random() * 100,
    timestamp: Date.now()
  });
}, 5000);

app.listen(3000, () => {
  console.log('SSE server running on port 3000');
});
// client.ts - SSE client
class SSEClient {
  private eventSource: EventSource | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;

  connect(url: string, handlers: {
    onMessage?: (data: any) => void;
    onError?: (error: Event) => void;
    onOpen?: () => void;
  }): void {
    this.eventSource = new EventSource(url);

    this.eventSource.onopen = () => {
      console.log('SSE connected');
      this.reconnectAttempts = 0;
      handlers.onOpen?.();
    };

    this.eventSource.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        handlers.onMessage?.(data);
      } catch (error) {
        console.error('Failed to parse SSE data:', error);
      }
    };

    this.eventSource.onerror = (error) => {
      console.error('SSE error:', error);
      handlers.onError?.(error);

      if (this.reconnectAttempts < this.maxReconnectAttempts) {
        this.reconnectAttempts++;
        setTimeout(() => {
          console.log('Reconnecting to SSE...');
          this.connect(url, handlers);
        }, 3000);
      }
    };

    // Custom event listeners
    this.eventSource.addEventListener('custom-event', (event: any) => {
      console.log('Custom event:', JSON.parse(event.data));
    });
  }

  disconnect(): void {
    this.eventSource?.close();
    this.eventSource = null;
  }
}

// Usage
const client = new SSEClient();
client.connect('http://localhost:3000/events', {
  onMessage: (data) => {
    console.log('Received:', data);
  },
  onOpen: () => {
    console.log('Connected to server');
  }
});

4. Socket.IO (Production-Ready)

// server.ts
import { Server } from 'socket.io';
import { createServer } from 'http';

const httpServer = createServer();
const io = new Server(httpServer, {
  cors: {
    origin: process.env.CLIENT_URL || 'http://localhost:3000',
    methods: ['GET', 'POST']
  },
  pingTimeout: 60000,
  pingInterval: 25000
});

// Middleware
io.use((socket, next) => {
  const token = socket.handshake.auth.token;
  if (isValidToken(token)) {
    next();
  } else {
    next(new Error('Authentication error'));
  }
});

io.on('connection', (socket) => {
  console.log(`User connected: ${socket.id}`);

  // Join room
  socket.on('join-room', (roomId: string) => {
    socket.join(roomId);
    socket.to(roomId).emit('user-joined', {
      userId: socket.id,
      timestamp: Date.now()
    });
  });

  // Handle messages
  socket.on('message', (data) => {
    const roomId = Array.from(socket.rooms)[1]; // First is own ID
    io.to(roomId).emit('message', {
      ...data,
      userId: socket.id,
      timestamp: Date.now()
    });
  });

  // Typing indicator
  socket.on('typing', (isTyping: boolean) => {
    const roomId = Array.from(socket.rooms)[1];
    socket.to(roomId).emit('user-typing', {
      userId: socket.id,
      isTyping
    });
  });

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

httpServer.listen(3001);

function isValidToken(token: string): boolean {
  // Implement token validation
  return true;
}

Best Practices

✅ DO

  • Implement reconnection logic with exponential backoff
  • Use heartbeat/ping-pong to detect dead connections
  • Validate and sanitize all messages
  • Implement authentication and authorization
  • Handle connection limits and rate limiting
  • Use compression for large payloads
  • Implement proper error handling
  • Monitor connection health
  • Use rooms/channels for targeted messaging
  • Implement graceful shutdown

❌ DON'T

  • Send sensitive data without encryption
  • Keep connections open indefinitely without cleanup
  • Broadcast to all users when targeted messaging suffices
  • Ignore connection state management
  • Send large payloads frequently
  • Skip message validation
  • Forget about mobile/unstable connections
  • Ignore scaling considerations

Performance Optimization

// Message batching
class MessageBatcher {
  private queue: any[] = [];
  private timer: NodeJS.Timeout | null = null;
  private batchSize = 10;
  private batchDelay = 100;

  constructor(
    private sendFn: (messages: any[]) => void
  ) {}

  add(message: any): void {
    this.queue.push(message);

    if (this.queue.length >= this.batchSize) {
      this.flush();
    } else if (!this.timer) {
      this.timer = setTimeout(() => this.flush(), this.batchDelay);
    }
  }

  private flush(): void {
    if (this.queue.length > 0) {
      this.sendFn(this.queue.splice(0));
    }
    if (this.timer) {
      clearTimeout(this.timer);
      this.timer = null;
    }
  }
}

Resources

适合场景

01

用户想查找某类 Agent Skill 时

02

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

03

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

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

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

能力 4

补充不同宿主或平台的使用分布数据

能力 5

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

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

平台分布

Claude Code

27.88%
按下载量换算81

Gemini CLI

21.35%
按下载量换算62

OpenCode

15.54%
按下载量换算45

Antigravity

12.26%
按下载量换算36

Cursor

8.01%
按下载量换算23

Codex

3.12%
按下载量换算9

安全审计

Gen Agent Trust Hub

未通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。

来源信息

继续浏览同类 Skills