AgentStack
SKILL verified MIT Self-run

Realtime Websockets

skill-nimadorostkar-claude-skills-collection-realtime-websockets · by nimadorostkar

Use when building realtime features with WebSockets or Server-Sent Events. Covers protocol choice, connection lifecycle, reconnection and backfill, scaling across instances, and backpressure.

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add skill-nimadorostkar-claude-skills-collection-realtime-websockets

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Realtime Websockets? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Realtime and WebSockets

Purpose

Build realtime features that behave correctly when the connection drops — which it will, constantly, on mobile networks. The hard part is not the socket; it is the state after the reconnect.

When to Use

  • Building live updates, chat, presence, collaborative editing, or streaming dashboards.
  • Choosing between WebSockets, SSE, and polling.
  • Scaling a socket server beyond one instance.
  • Diagnosing memory growth or dropped messages under load.

Capabilities

  • Protocol selection and trade-offs.
  • Connection lifecycle: handshake, auth, heartbeat, graceful close.
  • Reconnection with resume tokens and gap backfill.
  • Horizontal scaling with a pub/sub fan-out layer.
  • Backpressure and slow-consumer handling.

Inputs

  • Direction of data flow (server to client, or bidirectional).
  • Message volume, size, and acceptable latency.
  • Whether missed messages must be recovered or can be dropped.

Outputs

  • A protocol choice with a stated reason.
  • A reconnect path that restores correct state, not just a live socket.
  • A scaling design that works with more than one server instance.

Workflow

  1. Choose the simplest protocol that works — Server-to-client only? Use SSE: it is plain HTTP, reconnects automatically, and passes through proxies. Bidirectional and low-latency? WebSockets. Infrequent updates? Polling is not embarrassing.
  2. Authenticate at the handshake — Validate the token on connect; re-validate periodically for long-lived sockets. A socket opened an hour ago may belong to a revoked session.
  3. Heartbeat both ways — Ping/pong with a timeout. Without it, half-open connections accumulate and leak memory for hours.
  4. Design the resume — Every message carries a monotonic sequence number. On reconnect, the client sends its last-seen ID; the server replays the gap or tells it to resynchronize fully.
  5. Fan out via pub/sub — With more than one instance, a message published on instance A must reach a client connected to instance B. Redis pub/sub, NATS, or the broker you already have.
  6. Apply backpressure — Bound the per-connection send buffer. When it fills, drop the slow consumer rather than the server.

Best Practices

  • The reconnect path is the feature. Test it by killing the connection mid-stream, not by refreshing the page.
  • Never trust the client's claimed last-seen sequence without bounding the replay. A malicious or buggy client can request a million-message backfill.
  • Reconnect with exponential backoff and jitter. A server restart otherwise brings every client back simultaneously and takes it down again.
  • Sticky sessions are a workaround, not a design. Make any instance able to serve any client.
  • An unbounded outbound queue per connection is a memory leak with a slow client attached to it.
  • Send binary or compact JSON; per-message overhead dominates at high message rates.

Examples

Resumable stream with sequence numbers:

// Client
const ws = new WebSocket(`${URL}?resume_from=${lastSeq ?? ""}`);

ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (msg.seq !== lastSeq + 1 && lastSeq !== null) {
    // Gap detected: the server could not replay. Resynchronize from scratch.
    return resyncFromSnapshot();
  }
  lastSeq = msg.seq;
  apply(msg);
};

ws.onclose = () => scheduleReconnect(backoff.next()); // exponential + jitter
// Server: replay bounded, or instruct a full resync
const from = Number(url.searchParams.get("resume_from"));
const gap = currentSeq - from;

if (Number.isFinite(from) && gap > 0 && gap <= MAX_REPLAY) {
  for (const msg of await log.range(from + 1, currentSeq)) send(socket, msg);
} else {
  send(socket, { type: "resync_required", seq: currentSeq });
}

Notes

  • SSE is limited to six concurrent connections per domain on HTTP/1.1 browsers. Over HTTP/2 this limit effectively disappears — check what your load balancer actually terminates.
  • Load balancers commonly kill idle connections after 60 seconds. Your heartbeat interval must be shorter than the shortest idle timeout in the path.
  • For collaborative editing, message replay is not enough — you need CRDTs or operational transformation. Sequence numbers give you delivery, not convergence.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.