The Durable Object's ctx
Optional seams; the defaults are the deployment path
Handles a replica disconnecting.
Nothing is tracked, so nothing needs removing — the runtime drops the
socket from getWebSockets() on its own. The handler exists so the
application's class can forward it without a branch, and so the close is
acknowledged rather than left to the runtime's default.
The socket that closed
The close code the peer sent
The close reason the peer sent
Handles a socket error.
The runtime closes the socket itself, so this only prevents an unhandled rejection inside the application's class.
The socket that errored
Re-broadcasts one replica's message to every other connected replica.
The socket the message arrived on
The payload, forwarded byte for byte
Fans one replica's broadcast out to every other connected replica.
This class holds no state. Not as a simplification — as a correctness requirement. Sockets are accepted with
state.acceptWebSocket, the hibernation API, which lets the Workers runtime evict the Durable Object from memory while its connections stay open and re-run the constructor when the next message arrives. A membershipSetheld in a field would therefore empty itself on the first hibernation, and every test that never hibernates would still pass.state.getWebSockets()survives hibernation and is the only source of truth used here.The payload is re-broadcast verbatim, never parsed. That costs no CPU per fan-out, makes it impossible for this object to corrupt a frame, and — since a Durable Object class is deployed by the application rather than by this package — means a future widening of
RealtimeFrameneeds no redeploy of the object to carry the new field.The application owns the class; this owns the behavior:
Example
Since
0.2.0