{
  "schemaVersion": "1.0",
  "item": {
    "slug": "websocket",
    "name": "WebSocket",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/ivangdavila/websocket",
    "canonicalUrl": "https://clawhub.ai/ivangdavila/websocket",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/websocket",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=websocket",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "slug": "websocket",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-04T11:37:08.324Z",
      "expiresAt": "2026-05-11T11:37:08.324Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=websocket",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=websocket",
        "contentDisposition": "attachment; filename=\"websocket-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "websocket"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/websocket"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/websocket",
    "agentPageUrl": "https://openagent3.xyz/skills/websocket/agent",
    "manifestUrl": "https://openagent3.xyz/skills/websocket/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/websocket/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Reconnection (Always Forget)",
        "body": "Connections drop silently—TCP FIN may never arrive; don't assume onclose fires\nExponential backoff: 1s, 2s, 4s, 8s... cap at 30s—prevents thundering herd on server recovery\nAdd jitter: delay * (0.5 + Math.random())—prevents synchronized reconnection storms\nTrack reconnection state—queue messages during reconnect, replay after\nMax retry limit then surface error to user—don't retry forever silently"
      },
      {
        "title": "Heartbeats (Critical)",
        "body": "Ping/pong frames at protocol level—browser doesn't expose; use application-level ping\nSend ping every 30s, expect pong within 10s—no pong = connection dead, reconnect\nServer should ping too—detects dead clients, cleans up resources\nIdle timeout in proxies (60-120s typical)—heartbeat must be more frequent\nDon't rely on TCP keepalive—too infrequent, not reliable through proxies"
      },
      {
        "title": "Connection State",
        "body": "readyState: 0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED—check before sending\nBuffer messages while CONNECTING—send after OPEN\nbufferedAmount shows queued bytes—pause sending if backpressure building\nMultiple tabs = multiple connections—coordinate via BroadcastChannel or SharedWorker"
      },
      {
        "title": "Authentication",
        "body": "Token in URL query: wss://host/ws?token=xxx—simple but logged in access logs\nFirst message auth: connect, send token, wait for ack—cleaner but more round trips\nCookie auth: works if same origin—but no custom headers in WebSocket\nReauthenticate after reconnect—don't assume previous session valid"
      },
      {
        "title": "Scaling Challenges",
        "body": "WebSocket connections are stateful—can't round-robin between servers\nSticky sessions: route by client ID to same server—or use Redis pub/sub for broadcast\nEach connection holds memory—thousands of connections = significant RAM\nGraceful shutdown: send close frame, wait for clients to reconnect elsewhere"
      },
      {
        "title": "Nginx/Proxy Config",
        "body": "proxy_http_version 1.1;\nproxy_set_header Upgrade $http_upgrade;\nproxy_set_header Connection \"upgrade\";\nproxy_read_timeout 3600s;\n\nWithout these headers, upgrade fails—connection closes immediately\nproxy_read_timeout must exceed your ping interval—default 60s too short\nLoad balancer health checks: separate HTTP endpoint, not WebSocket"
      },
      {
        "title": "Close Codes",
        "body": "1000: normal closure; 1001: going away (page close)\n1006: abnormal (no close frame received)—usually network issue\n1008: policy violation; 1011: server error\n4000-4999: application-defined—use for auth failure, rate limit, etc.\nAlways send close code and reason—helps debugging"
      },
      {
        "title": "Message Handling",
        "body": "Text frames for JSON; binary frames for blobs/protobuf—don't mix without framing\nNo guaranteed message boundaries in TCP—but WebSocket handles framing for you\nOrder preserved per connection—messages arrive in send order\nLarge messages may fragment—library handles reassembly; set max message size server-side"
      },
      {
        "title": "Security",
        "body": "Validate Origin header on handshake—prevent cross-site WebSocket hijacking\nSame-origin policy doesn't apply—any page can connect to your WebSocket server\nRate limit per connection—one client can flood with messages\nValidate every message—malicious clients can send anything after connecting"
      },
      {
        "title": "Common Mistakes",
        "body": "No heartbeat—connection appears alive but is dead; messages go nowhere\nReconnect without backoff—hammers server during outage, prolongs recovery\nStoring state only in connection—lost on reconnect; persist critical state externally\nHuge messages—blocks event loop; stream large data via chunking\nNot handling bufferedAmount—memory grows unbounded if client slower than server"
      }
    ],
    "body": "Reconnection (Always Forget)\nConnections drop silently—TCP FIN may never arrive; don't assume onclose fires\nExponential backoff: 1s, 2s, 4s, 8s... cap at 30s—prevents thundering herd on server recovery\nAdd jitter: delay * (0.5 + Math.random())—prevents synchronized reconnection storms\nTrack reconnection state—queue messages during reconnect, replay after\nMax retry limit then surface error to user—don't retry forever silently\nHeartbeats (Critical)\nPing/pong frames at protocol level—browser doesn't expose; use application-level ping\nSend ping every 30s, expect pong within 10s—no pong = connection dead, reconnect\nServer should ping too—detects dead clients, cleans up resources\nIdle timeout in proxies (60-120s typical)—heartbeat must be more frequent\nDon't rely on TCP keepalive—too infrequent, not reliable through proxies\nConnection State\nreadyState: 0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED—check before sending\nBuffer messages while CONNECTING—send after OPEN\nbufferedAmount shows queued bytes—pause sending if backpressure building\nMultiple tabs = multiple connections—coordinate via BroadcastChannel or SharedWorker\nAuthentication\nToken in URL query: wss://host/ws?token=xxx—simple but logged in access logs\nFirst message auth: connect, send token, wait for ack—cleaner but more round trips\nCookie auth: works if same origin—but no custom headers in WebSocket\nReauthenticate after reconnect—don't assume previous session valid\nScaling Challenges\nWebSocket connections are stateful—can't round-robin between servers\nSticky sessions: route by client ID to same server—or use Redis pub/sub for broadcast\nEach connection holds memory—thousands of connections = significant RAM\nGraceful shutdown: send close frame, wait for clients to reconnect elsewhere\nNginx/Proxy Config\nproxy_http_version 1.1;\nproxy_set_header Upgrade $http_upgrade;\nproxy_set_header Connection \"upgrade\";\nproxy_read_timeout 3600s;\n\nWithout these headers, upgrade fails—connection closes immediately\nproxy_read_timeout must exceed your ping interval—default 60s too short\nLoad balancer health checks: separate HTTP endpoint, not WebSocket\nClose Codes\n1000: normal closure; 1001: going away (page close)\n1006: abnormal (no close frame received)—usually network issue\n1008: policy violation; 1011: server error\n4000-4999: application-defined—use for auth failure, rate limit, etc.\nAlways send close code and reason—helps debugging\nMessage Handling\nText frames for JSON; binary frames for blobs/protobuf—don't mix without framing\nNo guaranteed message boundaries in TCP—but WebSocket handles framing for you\nOrder preserved per connection—messages arrive in send order\nLarge messages may fragment—library handles reassembly; set max message size server-side\nSecurity\nValidate Origin header on handshake—prevent cross-site WebSocket hijacking\nSame-origin policy doesn't apply—any page can connect to your WebSocket server\nRate limit per connection—one client can flood with messages\nValidate every message—malicious clients can send anything after connecting\nCommon Mistakes\nNo heartbeat—connection appears alive but is dead; messages go nowhere\nReconnect without backoff—hammers server during outage, prolongs recovery\nStoring state only in connection—lost on reconnect; persist critical state externally\nHuge messages—blocks event loop; stream large data via chunking\nNot handling bufferedAmount—memory grows unbounded if client slower than server"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/ivangdavila/websocket",
    "publisherUrl": "https://clawhub.ai/ivangdavila/websocket",
    "owner": "ivangdavila",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/websocket",
    "downloadUrl": "https://openagent3.xyz/downloads/websocket",
    "agentUrl": "https://openagent3.xyz/skills/websocket/agent",
    "manifestUrl": "https://openagent3.xyz/skills/websocket/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/websocket/agent.md"
  }
}