class WebSocketService
implements IWebSocketService
Since 0.1.0

The WebSocket hub.

Constructors

WebSocketService(
runtime: IRuntimeServices,
options: ResolvedOptions,
available: boolean,
logger?: ILogger,
backplane?: IRealtimeBackplane,
behaviors?: readonly IIngressBehavior[]
)

Creates the service.

Parameters
runtime: IRuntimeServices

Runtime services (ids, monotonic clock, timers)

options: ResolvedOptions

Resolved plugin options

available: boolean

Whether the HTTP adapter can perform upgrades

optional
logger: ILogger

Optional logger used to report an upgrade-router failure; the HTTP adapter that consults the router has no logger of its own

optional
backplane: IRealtimeBackplane

Optional cross-replica transport. When present, every room broadcast is also published to it; when absent, rooms stay purely in-process, which is the behavior before the backplane existed.

optional
behaviors: readonly IIngressBehavior[]

The plugin-level ingress behaviours around onMessage, in declared order. Defaults to none: frame dispatch is then byte-identical to the pre-chain behaviour.

Properties

readonly
available: boolean

Whether the underlying HTTP adapter can perform WebSocket upgrades.

readonly
connectionCount: number

Current number of open connections across all routes.

readonly
roomCount: number

Current number of live rooms.

readonly
routeCount: number

Number of registered routes — reported by the health indicator.

Methods

closeAll(): void

Closes every connection and stops the heartbeat. Called from the plugin's shutdown hook (AI_GUIDELINES §14.5).

Since 0.1.0
createUpgradeRouter(): (request: Request) => Promise<WebSocketUpgradeDecision | null>

The router handed to the HTTP adapter. Matches the request against the route table, applies admission control, and builds the sink the adapter binds its native socket into.

Kept at its public single-parameter shape: the adapter consults it with the native request alone and has no principal to thread, so an adapter-side call routes the upgrade as anonymous. A failure is reported through the logger before it is turned into a 500 refusal, via the same #routeReported wrapper routeUpgrade uses, so the logging behavior has one implementation. The adapter-side UpgradeRouterStore also catches, but it runs inside @setu-ts/runtime, which has no logger and therefore has nowhere to put the cause — so the only place a routing bug can be made visible is here, at its source.

Since 0.2.0
deliverRemoteFrame(frame: RealtimeFrame): void

Delivers a frame that arrived from another replica to this replica's local room members.

Called only by the plugin's backplane subscription. It uses the room registry's local-only delivery path, so an arriving frame is never re-published — which would echo it around the cluster forever.

Frames of another kind, and frames this instance published itself, are ignored: one backplane topic carries both WebSocket rooms and SSE channels, and a room may legitimately share a name with a channel.

Since 0.4.0
peek(name: string): WebSocketRoom | undefined

Returns the named room if one already exists, without creating it.

The non-allocating counterpart to WebSocketService.room. A presence endpoint reading size for a request-supplied name must use this: room() registers one room per distinct name polled, and a room nobody joined is reclaimed only on the next disconnection.

Since 0.3.0
replaceIngressBehaviors(behaviors: readonly IIngressBehavior[]): void

Replaces the plugin-level ingress chain around onMessage with the resolved declared sequence.

Called once by the plugin's onInit hook, after every RegistryFactory entry of WebSocketPlugin({ behaviors }) has been resolved — the first phase at which the registry holds every capability, and still before the application serves, so no frame is ever dispatched without the final chain. With no factory behaviours configured it is never called with a non-empty list, and frame dispatch keeps the direct, synchronous form.

room(name: string): WebSocketRoom

Returns the named room, creating it on first use.

Creating is the point: the first call for a name registers a room. Use IWebSocketService.peek to read a caller-supplied name without registering anything.

route(
path: string,
): void

Registers a WebSocket route. Paths match exactly; the query string is ignored for matching and exposed to onOpen instead.

Since 0.3.0
routeUpgrade(
request: Request,
principal?: IPrincipal
): Promise<WebSocketUpgradeDecision | null>

The upgrade router the kernel terminal handler consults after the middleware pipeline has run without short-circuiting.

Delegates to the shared #routeReported reporting wrapper: a routing failure is written to the logger here, at its source, before it becomes a refusal. Calling #route directly would make this the one entry point whose failures are invisible — the kernel has no logger to write them to.