Protocol and connection model¶
WSRPC is a bidirectional RPC protocol carried by WebSocket text messages.
Both peers can register routes and initiate calls. Replies carry the call’s
identifier, allowing independent requests to complete in a different order.
It uses JSON envelopes with id, method, params, result and error.
These examples describe WSRPC’s protocol; they do not imply full JSON-RPC 2.0
compatibility.
Requests and replies¶
A request names a method and supplies its parameters:
{"id": 3, "method": "calculator.add", "params": {"a": 20, "b": 22}}
Successful replies echo the request identifier:
{"id": 3, "result": 42}
A failed method call returns an error payload:
{"id": 3, "error": {"type": "ValueError", "message": "Invalid value"}}
Python peers turn remote errors into ClientException. Local timeout and
transport exceptions are separate from a remote handler failure. Outgoing
Python calls accept keyword arguments. The receivers also understand positional
parameter arrays from other peers.
A connection can receive a new call while a local handler awaits a reverse call to the remote side. The read loop must continue processing replies in that situation. See the aiohttp callback example and the ASGI callback example.
Events and binary messages¶
An object without an id is an application event delivered to registered
event listeners. Use emit() when no RPC reply is needed.
Raw binary WebSocket messages are separate from the JSON RPC envelopes.
Binary hooks receive transport-specific input: aiohttp.WSMessage in the
aiohttp implementation and bytes in the ASGI implementation. Bytes nested
inside a JSON value are base64-encoded by the default serializer instead.
Routes and keepalive¶
Functions receive the RPC connection as their first argument. Route classes
attach state to one connection and expose methods through a policy such as
Route, AllowedRoute, PrefixRoute or WebSocketRoute.
A route object is created lazily. Calling its bare registered name invokes
its exposed init method; that call is explicit. Private names and methods
masked with noproxy remain inaccessible remotely.
The built-in ping route echoes its parameters. Application-level RPC ping
is separate from WebSocket PING/PONG frames, which ASGI servers handle at the
transport level. See each implementation’s configuration for keepalive,
concurrency and timeout behavior.