streams-and-websockets

Implement SSE streams and WebSocket upgrade handlers in Rango response routes.

Updated Nov 7, 2025
One-click install
npx skills add https://github.com/rangojs/rango --skill streams-and-websockets-rangojs
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: streams-and-websockets
Source: https://github.com/rangojs/rango/tree/main/packages/rangojs-router/skills/streams-and-websockets
Command: npx skills add https://github.com/rangojs/rango --skill streams-and-websockets-rangojs

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires @rangojs/router, agents.

What problem does it solve? Returning long-lived responses like Server-Sent Events streams and WebSocket upgrades from a router is tricky: middleware can reconstruct responses and break 101 status codes or drop the Cloudflare webSocket property, streams can leak when clients disconnect, and caching can corrupt replayed stream bodies. This Skill documents how Rango handles these cases so your real-time routes work correctly. ## Core Features & Use Cases - Server-Sent Events via path.stream(): Return a ReadableStream with text/event-stream framing on any runtime, with guidance on abort-signal cleanup and disabling proxy buffering. - WebSocket upgrades via path.any(): Handle status-101 upgrade responses on Cloudflare Workers, including manual WebSocketPair usage, Durable Object routing, and integration with the agents library's routeAgentRequest. - Middleware and caching semantics: Understand how the router forwards upgrade responses without reconstruction, why cookies should not be set on upgrades, and why SSE must never be wrapped in cache(). - Use Case: You are building a live dashboard on Cloudflare Workers and need a /events/ticks SSE endpoint plus a /ws WebSocket echo endpoint routed through a Durable Object, with auth enforced by middleware before the upgrade. ## Quick Start Add an SSE endpoint that streams a tick event every second and a WebSocket upgrade route to my Rango app's urlpatterns.

Frequently Asked Questions about streams-and-websockets

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a Server-Sent Events endpoint in Rango?

Use path.stream() to return a Response whose body is a ReadableStream with content-type text/event-stream. Encode each chunk as an event-stream frame and wire ctx.request.signal to close the stream when the client disconnects.

How do I handle a WebSocket upgrade on Cloudflare Workers?

Use path.any() and return a Response with status 101 and a webSocket property from a WebSocketPair. The router detects this shape and forwards it without reconstruction, preserving the 101 status and the webSocket property.

Can I use the agents library with Rango WebSocket routes?

Yes, routeAgentRequest from the agents package returns a 101 Response targeted at a Durable Object. Return it directly from a path.any() handler, falling back to a 404 Response when it returns null.

Why does my SSE stream break when I add caching middleware?

A cached ReadableStream is read once and replays an empty body on subsequent hits, so SSE routes must never be wrapped in cache(). path.stream is already excluded from response-route caching, but avoid layering a custom cache middleware on top.

Can middleware set cookies on a WebSocket upgrade response?

Stub header writes are merged in place only on a best-effort basis, and browsers never read headers during the WS handshake anyway. Set cookies on a prior HTTP request and read them at upgrade time via ctx.request.headers instead.

Does WebSocket upgrade work on Node or Bun runtimes?

No, status-101 Response construction is a Cloudflare workerd feature. Node requires its HTTP server to perform the upgrade, and Bun uses its native upgrade() API, so WebSocket routes only work on workerd or its dev emulation.