算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
software-realtime【设计与创意】Designs real-time and collaborative systems. Use when building chat, presence, live dashboards, collaborative editing, WebSockets, SSE, WebTransport, or local-first sync.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Use this skill for transport choice, collaborative-state design, presence models, reconnection behavior, and multi-node real-time scaling. It owns SSE, WebSocket, CRDT, and managed real-time decisions, not generic backend APIs or frontend-only state management.
| Task | Use |
|---|---|
| Transport selection | references/transport-selection.md |
| Collaboration, presence, and recovery | references/collaboration-patterns.md |
| Vendor traps and version-pinned gotchas | references/vendor-traps.md |
| Edge platforms, CRDT picks, channel limits | references/edge-realtime.md |
| WebSocket handshake, message, and second-connection checks | scripts/check_ws_smoke.py |
| Source map | data/sources.json |
| Use Case | Transport | Reason |
|---|---|---|
| Dashboards, feeds, notifications | SSE | One-way, HTTP-native, browser handles reconnect |
| Chat, multiplayer, live cursors, client-originated messages | WebSocket | Bidirectional session required |
| Sub-frame media/game state where occasional loss beats head-of-line blocking | WebTransport | Unreliable + unordered datagrams over QUIC; check its current Baseline status and browser support before committing infra |
| Peer-to-peer audio/video or direct browser-to-browser data | WebRTC (media tracks or data channels) | Budget for TURN relay and consider an SFU when mesh upload grows with participants |
| Shared documents / state that must merge under concurrency | CRDT-backed collaboration | Avoids hand-rolled merge logic |
| Team owns connection infra as a core advantage | Custom WebSocket + pub/sub | Full control |
| Team wants to avoid connection layer ops | Managed pub/sub (Ably, Pusher, Supabase Realtime, PartyKit) or serverless WebSocket (AWS API Gateway WebSocket, Azure Web PubSub) | Faster path, vendor limits apply |
WebTransport reality check: check browser support and test the selected server, CDN, load balancer, and proxy path. If datagrams are required, verify that the negotiated mode supports unreliable delivery; a reliable-only fallback will not meet that need. Default to WebSocket unless the workload needs datagrams or independent streams, and retain a tested fallback where the required mode is unavailable.
Relational sync vs document collaboration: Zero syncs server-authorized queries, Electric syncs Postgres shapes, and PowerSync Sync Streams select an offline SQLite replica. These fit relational app state and partial offline reads; use a CRDT for free-form concurrent document edits. Check each engine's current query scope, permission enforcement, write/conflict path, and deployment model before choosing. See collaboration patterns.
provider.awareness object, not in the durable document.Reconnect and resync contract.
Give each durable update a monotonic sequence or cursor and each client operation a stable ID. On reconnect, the client sends its last applied cursor; the server returns the missing range or a fresh snapshot plus a new cursor. Define retention expiry explicitly: when the gap is no longer replayable, force snapshot resync instead of pretending the live stream is complete.
Origin on every handshake to block cross-site WebSocket hijacking; Origin alone does not authenticate non-browser clients. Check authorization again on each room join and action. OWASP guidance.op_id to each outbound message for idempotent replay; cap queue size and surface an error if exceeded.Heartbeat interval budget (re-derive from your own proxy/LB idle timeout, never reuse this number): if the tightest intermediary idle timeout in the path (LB, corporate proxy, CDN) is 60s, send heartbeats at ≤ half that (≤30s) so at least one heartbeat lands before the timeout fires even under jitter; set server-side dead-connection detection at 2–3× the heartbeat interval (60–90s here) so one dropped heartbeat frame does not trigger a false disconnect.
Connection memory sizing: measure socket buffers, auth/subscription state, and the bounded outbound queue under representative load. Check file descriptors and network limits separately from memory.
Fan-out math: for N subscribed clients each receiving M messages per second, budget N × M outbound sends per second before framing and TLS. Measure broker and egress capacity at your payload size; shard hot rooms when the measured ceiling approaches demand.
| Trap | Consequence | Fix |
|---|---|---|
| Auth only on initial handshake; reconnect path undefined | Reconnect after token expiry fails silently | Handle token refresh in reconnect loop |
| Treating presence/typing signals as durable truth | Stale cursors on reconnect; unbounded storage growth | Ephemeral TTL store; derive expiry from heartbeat interval |
Offline queues without stable op_id and dedupe policy | Duplicate state on replay | Assign op_id before queuing; server deduplicates idempotently |
| Scaling to multi-node before single-node protocol is stable | Fan-out bugs are hard to reproduce across nodes | Validate room semantics on a single node first |
| Choosing WebSocket by habit for one-way server push | Unnecessary bidirectional session overhead | Evaluate SSE; if client never sends messages, SSE is cheaper |
| Adopting WebTransport because of browser support alone | The deployed request path may not pass the selected transport | Test on target networks and intermediaries; keep a tested fallback |
| Sizing a WebSocket fleet from a published per-connection memory or DO connection-count figure without measuring on your own runtime | Instance falls over well below the "documented" ceiling because TLS termination point, message size, and per-connection app state differ from the vendor's benchmark | Load test at target CCU with production-representative payloads before trusting any vendor capacity number |
Five numbered scenarios covering the most common real-time design moments. Each lists the shortest path using patterns above.
user_id; include a last_seen timestamp on each heartbeat.SETEX) separate from durable document state.op_id for deduplication on replay.op_id; idempotent apply means safe replay without double-writes.connecting, connected, disconnected) so the UI can show status.Y.Doc per document; connect via a WebSocket provider (y-websocket or PartyKit).Y.encodeStateAsUpdate format.provider.awareness object; never write it to the doc.Y.applyUpdate with the server state before broadcasting local pending updates.Content-Type: text/event-stream.id: fields and implement replay from Last-Event-ID; the header alone does not restore missed events.: keepalive) every 25 seconds to prevent proxy timeout.room:{id}:shard:{n}) based on user_id % shard_count.When prior decisions or pitfalls are relevant, consult learnings.consolidated.md if present; use learnings.md only for needed history or as the available fallback. Otherwise skip both.
After applying it, if you encountered a pattern worth remembering, a mistake worth preventing, or a domain fact that surprised you, append one dated bullet to learnings.md via agents-skills-feedback-loop/scripts/append_learning.py. Do not modify SKILL.md itself.