WebSocket
Serve your procedures over a WebSocket and keep one connection for every call.
Server via crossws (optional peer). Same path / createContext / onError as HTTP. Streams are not supported - a stream procedure is INTERNAL_ERROR.
Security: The WS handler does not authenticate connections by default. Use
createContextto verify credentials on every message, or guard the upgrade path itself. An unauthenticated socket can call any procedure.
import serveserve({
websocket: {
upgrade(req: Request): Response | undefined;
message(peer: Peer, message: Message): Promise<void>;
}
websocket: handle<{
ping: ProcedureDef<{}, undefined, "pong">;
}, {
user: string;
}>(router: {
ping: ProcedureDef<{}, undefined, "pong">;
}, opts?: WsHandleOptions<{
user: string;
}> | undefined): {
upgrade(req: Request): Response | undefined;
message(peer: Peer, message: Message): Promise<void>;
}
handle(const router: {
ping: ProcedureDef<{}, undefined, "pong">;
}
router, {
path?: string | undefinedpath: "/rpc",
createContext?: ((peer: Peer) => {
user: string;
} | Promise<{
user: string;
}>) | undefined
createContext: (peer: Peerpeer) => ({
user: stringuser: var String: StringConstructor
(value?: any) => string
Allows manipulation and formatting of text strings and determination and location of substrings within strings.String(peer: Peerpeer.context: Record<string, unknown>context["user"] ?? ""),
}),
onError?: ((err: unknown, peer: Peer) => void) | undefinedonError: (err: unknownerr) => var console: Consoleconsole.Console.error(...data: any[]): voidThe **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)error(err: unknownerr),
}),
});
Client from tacho/client/ws. One socket. .ready and .close().
const const ws: RPCClient<{
ping: ProcedureDef<{}, undefined, "pong">;
}> & {
close: (code?: number, reason?: string) => void;
ready: Promise<void>;
}
ws = createClient<{
ping: ProcedureDef<{}, undefined, "pong">;
}>(opts: WsClientOptions): RPCClient<{
ping: ProcedureDef<{}, undefined, "pong">;
}> & {
close: (code?: number, reason?: string) => void;
ready: Promise<void>;
}
createClient<type Router = {
ping: ProcedureDef<{}, undefined, "pong">;
}
Router>({
url: stringurl: "ws://localhost:3000",
protocols?: string | string[] | undefinedprotocols: "tacho",
});
await const ws: RPCClient<{
ping: ProcedureDef<{}, undefined, "pong">;
}> & {
close: (code?: number, reason?: string) => void;
ready: Promise<void>;
}
ws.ready: Promise<void>ready;
await const ws: RPCClient<{
ping: ProcedureDef<{}, undefined, "pong">;
}> & {
close: (code?: number, reason?: string) => void;
ready: Promise<void>;
}
ws.ping: (input?: undefined, opts?: CallOptions | undefined) => Promise<"pong">ping();
const ws: RPCClient<{
ping: ProcedureDef<{}, undefined, "pong">;
}> & {
close: (code?: number, reason?: string) => void;
ready: Promise<void>;
}
ws.close: (code?: number, reason?: string) => voidclose();
| option | |
|---|---|
url |
WebSocket URL. |
protocols |
Passed to WebSocket. |
WebSocket |
Custom constructor. Defaults to global. |
serializer |
Custom serializer. |