SocketRoute
Documentation for Redweb 0.13.2. Install that exact version when following these examples.
Defines a WebSocket endpoint and owns its handlers, services, clients, and opt-in multiplayer policies. Routes can add bounded admission, transport limits, ordered work, heartbeat, rooms, resumable sessions, distribution, draining, metrics, and protocol negotiation without changing legacy routes.
Explain it like I’m five
A SocketRoute is a room with its own door and rules. The URL chooses the room; message.type chooses which handler inside the room receives the message.
When should I use it?
Create one whenever a WebSocket path represents a distinct protocol, trust boundary, workload, or group of multiplayer resources.
Follow the example
This API pattern illustrates the named surface; it may require application-owned classes, credentials, or assets. Start from a complete recipe for a runnable application.
const { SocketRoute } = require('redweb')
const { ChatHandler } = require('./handlers/ChatHandler')
const { ClockService } = require('./services/ClockService')
class ChatRoute extends SocketRoute {
constructor() {
super({
path: '/chat',
handlers: [ChatHandler],
services: [ClockService],
allowDuplicateConnections: true,
websocketOptions: {
maxPayload: 1024 * 1024,
perMessageDeflate: false,
},
})
}
}- The /match path selects the route during the WebSocket upgrade.
- Admission and capacity checks run before the connection becomes an active client.
- Messages are dispatched by type to BaseHandler instances while route services and registries share the same lifecycle.
Options
- path: WebSocket path (required)
- handlers: array of handler classes (required)
- services: array of SocketService subclasses (optional)
- allowDuplicateConnections: allow multiple clients from the same IP
- websocketOptions: options passed to ws WebSocketServer, such as maxPayload or perMessageDeflate
- admission: authenticate, validate origins, and optionally place a client before upgrade
- maxPendingUpgrades: finite concurrent admission/negotiation work (default 64)
- limits: connection, message-rate, pending-message, and outbound-buffer ceilings
- orderedMessages: serialize each connection through a bounded queue
- heartbeat: one route-level half-open connection monitor
- rooms and sessions: bounded grouping and expiring application-issued ownership
- distribution: optional bounded broker adapter; no broker is bundled or required
- drainHandlers: track handler work and expose a cooperative shutdown signal
- protocol: version negotiation, stable envelopes/error codes, and optional binary codecs
Methods and members
constructor({ path, handlers, services, allowDuplicateConnections, websocketOptions })
Validates input, instantiates handlers/services, sets up a ws server for the path with any websocketOptions, and registers connection listeners.
addHandler(HandlerClass)
Adds another handler class unless a handler with the same name already exists.
handleConnection(socket, req)
Stores the client (deduping by IP unless allowed), decorates the socket with sendJson/broadcast, and wires close/error/message listeners.
handleMessage(socket, data)
Parses JSON text frames, finds the handler matching data.type; on success delegates to handler.handleMessage, otherwise replies with an error and closes the socket.
handleBinaryMessage(socket, buffer)
Handles binary frames separately from JSON text frames and delegates to a handler selected by acceptsBinary(socket, buffer).
handleClose(socket, ip)
Removes the client from the registry and triggers an optional connectionCloseCallback.
shutdown()
Marks the route draining, stops services, bounds handler/adapter cleanup, closes clients, and releases every route-owned resource.
beginDrain()
Flips readiness and rejects new upgrades before shutdown work begins.
isReady()
Reports whether the route is accepting upgrades and any required distribution adapter is healthy.
publish(type, payload)
Publishes through the optional bounded distribution adapter and resolves to a success boolean.
handleError(socket, error, ip)
Logs socket errors; override for custom reporting.
What should I watch for?
Keep routing decisions out of message.action branches. Prefer one route per protocol area and one handler per message type.