Skip to content

RpcServer

Runs server-side handlers for RPC groups.

This module connects typed handlers for an RpcGroup to a server Protocol. It receives client messages, decodes request payloads, runs matching handlers and middleware, tracks in-flight requests, handles acknowledgements and interrupts, and sends responses back to clients. It also provides constructors and layers for decoded messages, HTTP, WebSocket, sockets, stdio, and worker runner protocols.

20 exports Added in v4.0.0 Source

Constructors

Creates an RPC server for an already-decoded message channel, running handlers for a group and sending decoded server responses through onFromServer.

Signature

declare const makeNoSerialization: <Rpcs extends Rpc.Any>(
  group: RpcGroup.RpcGroup<Rpcs>,
  options: {
    readonly concurrency?: number | "unbounded";
    readonly disableClientAcks?: boolean;
    readonly disableFatalDefects?: boolean;
    readonly disableSpanPropagation?: boolean;
    readonly disableTracing?: boolean;
    readonly onFromServer: (response: FromServer<Rpcs>) => Effect.Effect<void>;
    readonly spanAttributes?: Record<string, unknown>;
    readonly spanPrefix?: string;
  },
) => Effect.Effect<
  RpcServer<Rpcs>,
  never,
  Rpc.ToHandler<Rpcs> | Rpc.Middleware<Rpcs> | Scope.Scope
>;

Layers

layer

Added in v4.0.0 Source

Provides a scoped layer that starts an RPC server for a group using the current server Protocol.

Signature

declare function layer<Rpcs extends Any>(
  group: RpcGroup<Rpcs>,
  options?: {
    readonly concurrency?: number | "unbounded";
    readonly disableFatalDefects?: boolean;
    readonly disableTracing?: boolean;
    readonly spanAttributes?: Record<string, unknown>;
    readonly spanPrefix?: string;
  },
): Layer<never, never, Protocol | ToHandler<Rpcs> | Middleware<Rpcs> | ServicesServer<Rpcs>>;

layerHttp

Added in v4.0.0 Source

Creates a RPC server that registers a HTTP route with a HttpRouter.

Details

Defaults to using websockets for communication, but can be configured to use HTTP.

Signature

declare function layerHttp<Rpcs extends Any>(options: {
  readonly concurrency?: number | "unbounded";
  readonly disableFatalDefects?: boolean;
  readonly disableTracing?: boolean;
  readonly group: RpcGroup<Rpcs>;
  readonly path: PathInput;
  readonly protocol?: "http" | "websocket";
  readonly spanAttributes?: Record<string, unknown>;
  readonly spanPrefix?: string;
}): Layer<
  never,
  never,
  HttpRouter | RpcSerialization | ToHandler<Rpcs> | Middleware<Rpcs> | ServicesServer<Rpcs>
>;

Provides a server Protocol that uses HTTP POST requests for RPC communication.

Signature

declare function layerProtocolHttp(options: {
  readonly path: PathInput;
}): Layer<Protocol, never, HttpRouter | RpcSerialization>;

RPC protocol that uses SocketServer for communication.

Signature

declare const layerProtocolSocketServer: Layer.Layer<
  Protocol,
  never,
  RpcSerialization.RpcSerialization | SocketServer.SocketServer
>;

Provides a server Protocol that reads RPC messages from Stdio.stdin and writes encoded responses to Stdio.stdout.

Signature

declare const layerProtocolStdio: Layer.Layer<
  Protocol,
  never,
  RpcSerialization.RpcSerialization | Stdio
>;

RPC protocol that uses WebSockets for communication.

Signature

declare function layerProtocolWebsocket(options: {
  readonly path: PathInput;
}): Layer<Protocol, never, HttpRouter | RpcSerialization>;

Provides a server Protocol backed by the current WorkerRunnerPlatform.

Signature

declare const layerProtocolWorkerRunner: Layer.Layer<
  Protocol,
  WorkerError,
  WorkerRunner.WorkerRunnerPlatform
>;

Models

RpcServer interface

Added in v4.0.0 Source

The decoded RPC server boundary, accepting client messages for a client id and allowing that client to be disconnected.

Signature

interface RpcServer<A extends Rpc.Any> {
  readonly disconnect: (clientId: number) => Effect<void>;
  readonly write: (
    clientId: number,
    message: FromClient<A>,
    options?: {
      readonly onRequest?: <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
    },
  ) => Effect<void>;
}

Protocols

Creates an HTTP server Protocol and registers its request handler as a POST route on the current HttpRouter.

Signature

declare const makeProtocolHttp: (options: {
  readonly path: HttpRouter.PathInput;
}) => Effect.Effect<
  Protocol["Service"],
  never,
  RpcSerialization.RpcSerialization | HttpRouter.HttpRouter
>;

Creates a server Protocol backed by the current SocketServer, accepting socket connections and routing decoded RPC messages.

Signature

declare const makeProtocolSocketServer: Effect<{
  readonly clientIds: Effect<ReadonlySet<number>>;
  readonly disconnects: Dequeue<number>;
  readonly end: (clientId: number) => Effect<void>;
  readonly initialMessage: Effect<Option<unknown>>;
  readonly run: (f: (clientId: number, data: FromClientEncoded) => Effect<void>) => Effect<never>;
  readonly send: (clientId: number, response: FromServerEncoded, transferables?: readonly Array<Transferable>) => Effect<void>;
  readonly supportsAck: boolean;
  readonly supportsSpanPropagation: boolean;
  readonly supportsTransferables: boolean;
}, never, Scope | RpcSerialization | SocketServer>

Creates a server Protocol that reads RPC messages from Stdio.stdin and writes encoded responses to Stdio.stdout.

Signature

declare const makeProtocolStdio: Effect<{
  readonly clientIds: Effect<ReadonlySet<number>>;
  readonly disconnects: Dequeue<number>;
  readonly end: (clientId: number) => Effect<void>;
  readonly initialMessage: Effect<Option<unknown>>;
  readonly run: (f: (clientId: number, data: FromClientEncoded) => Effect<void>) => Effect<never>;
  readonly send: (clientId: number, response: FromServerEncoded, transferables?: readonly Array<Transferable>) => Effect<void>;
  readonly supportsAck: boolean;
  readonly supportsSpanPropagation: boolean;
  readonly supportsTransferables: boolean;
}, never, Scope | Stdio | RpcSerialization>

Creates a websocket server Protocol and registers its upgrade handler as a GET route on the current HttpRouter.

Signature

declare const makeProtocolWebsocket: (options: {
  readonly path: HttpRouter.PathInput;
}) => Effect.Effect<
  Protocol["Service"],
  never,
  RpcSerialization.RpcSerialization | HttpRouter.HttpRouter
>;

Creates an HTTP request/response server Protocol together with an HTTP effect that decodes the current request and streams or returns encoded RPC responses.

Signature

declare const makeProtocolWithHttpEffect: Effect.Effect<
  {
    readonly httpEffect: Effect.Effect<
      HttpServerResponse.HttpServerResponse,
      never,
      Scope.Scope | HttpServerRequest.HttpServerRequest
    >;
    readonly protocol: Protocol["Service"];
  },
  never,
  RpcSerialization.RpcSerialization
>;

Creates a websocket server Protocol together with an HTTP effect that upgrades the current request to a websocket and attaches it to the protocol.

Signature

declare const makeProtocolWithHttpEffectWebsocket: Effect.Effect<
  {
    readonly httpEffect: Effect.Effect<
      HttpServerResponse.HttpServerResponse,
      never,
      Scope.Scope | HttpServerRequest.HttpServerRequest
    >;
    readonly protocol: Protocol["Service"];
  },
  never,
  RpcSerialization.RpcSerialization
>;

Creates a server Protocol backed by WorkerRunnerPlatform, routing worker messages to the RPC server and server responses back to workers.

Signature

declare const makeProtocolWorkerRunner: Effect.Effect<
  Protocol["Service"],
  WorkerError,
  WorkerRunner.WorkerRunnerPlatform | Scope.Scope
>;

Running

make

Added in v4.0.0 Source

Runs an RPC server for a group using the current server Protocol, decoding requests, invoking handlers, encoding responses, and managing in-flight request lifetime.

Signature

declare const make: <Rpcs extends Rpc.Any>(
  group: RpcGroup.RpcGroup<Rpcs>,
  options?: {
    readonly concurrency?: number | "unbounded";
    readonly disableFatalDefects?: boolean;
    readonly disableTracing?: boolean;
    readonly spanAttributes?: Record<string, unknown>;
    readonly spanPrefix?: string;
  },
) => Effect.Effect<
  never,
  never,
  Protocol | Rpc.ToHandler<Rpcs> | Rpc.Middleware<Rpcs> | Rpc.ServicesServer<Rpcs>
>;

toHttpEffect

Added in v4.0.0 Source

Starts an RPC server for a group and returns the HTTP request/response effect that serves the non-websocket HTTP RPC protocol.

Signature

declare const toHttpEffect: <Rpcs extends Rpc.Any>(
  group: RpcGroup.RpcGroup<Rpcs>,
  options?: {
    readonly disableFatalDefects?: boolean;
    readonly disableTracing?: boolean;
    readonly spanAttributes?: Record<string, unknown>;
    readonly spanPrefix?: string;
  },
) => Effect.Effect<
  Effect.Effect<
    HttpServerResponse.HttpServerResponse,
    never,
    Scope.Scope | HttpServerRequest.HttpServerRequest
  >,
  never,
  | Scope.Scope
  | RpcSerialization.RpcSerialization
  | Rpc.ToHandler<Rpcs>
  | Rpc.Middleware<Rpcs>
  | Rpc.ServicesServer<Rpcs>
>;

Starts an RPC server for a group and returns the HTTP effect that upgrades requests to the websocket RPC protocol.

Signature

declare const toHttpEffectWebsocket: <Rpcs extends Rpc.Any>(
  group: RpcGroup.RpcGroup<Rpcs>,
  options?: {
    readonly disableFatalDefects?: boolean;
    readonly disableTracing?: boolean;
    readonly spanAttributes?: Record<string, unknown>;
    readonly spanPrefix?: string;
  },
) => Effect.Effect<
  Effect.Effect<
    HttpServerResponse.HttpServerResponse,
    never,
    Scope.Scope | HttpServerRequest.HttpServerRequest
  >,
  never,
  | Scope.Scope
  | RpcSerialization.RpcSerialization
  | Rpc.ToHandler<Rpcs>
  | Rpc.Middleware<Rpcs>
  | Rpc.ServicesServer<Rpcs>
>;

Services

Protocol

Added in v4.0.0 Source

Defines the service interface for an RPC server transport, responsible for receiving encoded client messages, sending encoded responses, tracking clients, and declaring transport capabilities.

When to use

Use to provide the transport boundary for RPC servers over HTTP, WebSocket, workers, sockets, or custom protocols.

Signature

declare class Protocol extends Shape<"effect/rpc/RpcServer/Protocol", {
  readonly clientIds: Effect<ReadonlySet<number>>;
  readonly disconnects: Dequeue<number>;
  readonly end: (clientId: number) => Effect<void>;
  readonly initialMessage: Effect<Option<unknown>>;
  readonly run: (f: (clientId: number, data: FromClientEncoded) => Effect<void>) => Effect<never>;
  readonly send: (clientId: number, response: FromServerEncoded, transferables?: readonly Array<Transferable>) => Effect<void>;
  readonly supportsAck: boolean;
  readonly supportsSpanPropagation: boolean;
  readonly supportsTransferables: boolean;
}, this> {
  constructor(_: never);
  static make: <EX, RX>(f: (write: (clientId: number, data: FromClientEncoded) => Effect<void>) => Effect<Omit<{
    readonly clientIds: Effect<ReadonlySet<number>>;
    readonly disconnects: Dequeue<number>;
    readonly end: (clientId: number) => Effect<void>;
    readonly initialMessage: Effect<Option<unknown>>;
    readonly run: (f: (clientId: number, data: FromClientEncoded) => Effect<void>) => Effect<never>;
    readonly send: (clientId: number, response: FromServerEncoded, transferables?: readonly Array<Transferable>) => Effect<void>;
    readonly supportsAck: boolean;
    readonly supportsSpanPropagation: boolean;
    readonly supportsTransferables: boolean;
  }, "run">, EX, RX>) => Effect<{
    readonly clientIds: Effect<ReadonlySet<number>>;
    readonly disconnects: Dequeue<number>;
    readonly end: (clientId: number) => Effect<void>;
    readonly initialMessage: Effect<Option<unknown>>;
    readonly run: (f: (clientId: number, data: FromClientEncoded) => Effect<void>) => Effect<never>;
    readonly send: (clientId: number, response: FromServerEncoded, transferables?: readonly Array<Transferable>) => Effect<void>;
    readonly supportsAck: boolean;
    readonly supportsSpanPropagation: boolean;
    readonly supportsTransferables: boolean;
  }, EX, RX>;
}