rpc.endpoint
import rpc
Everything here is re-exported by
rpc, soimport rpcis enough and the names are called asrpc.*. Importingrpc.endpointon its own works too and reaches the same definitions.
Endpoint: one side of a JSON-RPC connection. It is a
Service on a connection: it answers the
requests and notifications the other side sends, and sends its own.
JSON-RPC makes no difference between a client and a server, so the same
endpoint can do both on one connection.
Re-exported by rpc.
Classes
Endpoint
class rpc.Endpoint < Service
One side of a JSON-RPC connection over a transport.
An endpoint is a Service, so its handlers,
its fallback and its batch limit work exactly as a service’s do. The
connection adds the other direction: an endpoint calls the other side
with request(), request_batch(), send_request() and notify(),
and a handler on one can defer() its answer and send it later.
import rpc
import isolate
var ends = rpc.pipe()
# The server runs on an isolate of its own, answering until the
# client closes its end.
isolate.spawn(@(transport) {
import rpc
rpc.endpoint(transport)
.on_request('add', @(params) => params[0] + params[1])
.serve()
}, ends[1])
var client = rpc.endpoint(ends[0])
echo client.request('add', [2, 3]) # 5
client.close()
An endpoint reads its transport in one of three ways. serve() reads
and answers until the connection ends, on the isolate that calls it.
listen() reads on an isolate of its own and returns a Channel of
what arrives, for a program that waits on other things as well; it
passes each one to dispatch() when it is ready to handle it. A program
that reads the transport itself, such as one polling many connections,
hands what it reads to feed(). Every handler runs on the isolate that
owns the endpoint, and everything is sent from there.
- printable — has a
@to_string(), soechoandprint()show something useful
Constructor
rpc.Endpoint(transport)
Returns a new Endpoint over transport. Its messages are
framed the way the transport keeps them apart: with the transport’s own
framing() when it has one, as a WebSocket does, and with a
HeaderFraming otherwise.
Parameters
transport(any) — A transport; seerpc.transport.
Endpoint.set_framing()
rpc.Endpoint.set_framing(framing) -> Endpoint
Sets how messages are told apart in the stream. Set it before
listen(), which hands the framing to the isolate it reads on.
Parameters
framing(HeaderFraming|LineFraming|MessageFraming) — Default the transport’s ownframing(), orHeaderFraming().
Returns Endpoint — itself.
Endpoint.notify()
rpc.Endpoint.notify(method: string, params)
Sends a notification: calls method on the other side and expects
nothing back.
Parameters
method(string)params(list|dict|nil) — Defaultnil, which sends none.
Raises RpcClosedError when the endpoint has been closed.
Endpoint.send_request()
rpc.Endpoint.send_request(method: string, params, callback: function)
Sends a request and returns at once; callback is called with the
answer when it arrives, on the isolate that owns the endpoint, while it
serves, waits on a request, or dispatches.
Parameters
method(string)params(list|dict|nil)callback(function(2)) — Called with the result andnil, or withniland the error: an {RpcError} the other side answered with, or an {RpcClosedError} when the connection ended first.
Returns — int: The request’s id.
Raises RpcClosedError when the endpoint has been closed.
Endpoint.request()
rpc.Endpoint.request(method: string, params, timeout: ?number)
Sends a request and waits for its answer, handling whatever else arrives
in the meantime as serve() would.
var sum = endpoint.request('add', [2, 3])
An error answer that names no request, which the other side sends for a
message it cannot read at all, goes to on_error() rather than to any
one request.
Parameters
method(string)params(list|dict|nil)timeout(?number) — The most seconds to wait. Defaultnil, which waits until the answer comes or the connection ends. A timeout needs the endpoint to be listening; one reading its transport itself waits as long as the transport’s reads do.
Returns — any: The result the other side answered with.
Raises RpcError when the other side answers with an error.
Raises RpcClosedError when the endpoint has been closed, or the
connection ends before the answer.
Raises RpcTimeoutError when timeout runs out first.
Endpoint.request_batch()
rpc.Endpoint.request_batch(calls: list, timeout: ?number)
Sends several requests as one batch and waits for every answer, handling
whatever else arrives in the meantime as request() does. The other
side may answer them in any order; they come back in the order of
calls.
var sums = endpoint.request_batch([['add', [1, 2]], ['add', [3, 4]]])
Parameters
calls(list) — Each call as a pair,[method, params].timeout(?number) — The most seconds to wait for every answer, as forrequest().
Returns — list: For each call, in order, the result the other side answered with, or the {RpcError} it answered with.
Raises ValueError when calls is empty, or a call is not a
[method, params] pair.
Raises RpcClosedError when the endpoint has been closed, or the
connection ends before every answer.
Raises RpcTimeoutError when timeout runs out first.
Endpoint.send()
rpc.Endpoint.send(message)
Sends a message as it is: a Request, a
Notification, a
Response, or a list of them as a batch.
Parameters
message(Request|Notification|Response|list)
Raises RpcClosedError when the endpoint has been closed.
Endpoint.serve()
rpc.Endpoint.serve()
Reads and answers messages until the connection ends, stop() is
called, or the endpoint is closed. On a listening endpoint, it takes
what arrives from the Channel listen() returned.
A message that is not valid UTF-8, or not valid JSON, is answered with
PARSE_ERROR and an id of nil.
Raises RpcFramingError when the stream cannot be read past a
message.
Endpoint.stop()
rpc.Endpoint.stop()
Makes serve() return once the message it is handling is done.
Endpoint.listen()
rpc.Endpoint.listen() -> isolate.Channel
Starts reading the transport on an isolate of its own, and returns the
Channel each message is put on as it arrives, already decoded from
JSON. Pass each item taken from it to dispatch(), on the isolate that
owns the endpoint, when the program is ready to handle it.
var inbox = endpoint.listen()
while !endpoint.is_closed() {
var ready = isolate.select([inbox, work], 0.5)
if ready[0] == inbox {
endpoint.dispatch(ready[1])
}
}
Each item is a dictionary whose kind says what arrived:
{ kind: 'message', text, value }: a message, as its JSON text and the value decoded from it.{ kind: 'unreadable', text, message }: a message that is not valid JSON, withtextnilwhen it is not valid UTF-8 either, and the parse error it is answered with.{ kind: 'closed' }: the end of the connection.{ kind: 'failed', message }: a failure reading the transport, which ends the connection.
Calling listen() again returns the same Channel.
Returns isolate.Channel
Raises ValueError when the transport cannot be read from another
isolate; see can_listen() in rpc.transport.
Endpoint.dispatch()
rpc.Endpoint.dispatch(item: dict)
Handles one item taken from the Channel listen() returned: answers a
message, or marks the connection ended. A failed connection is reported
to on_error() with an RpcClosedError.
Parameters
item(dict)
Endpoint.handle()
rpc.Endpoint.handle(value)
Handles one message already decoded from JSON, or a batch of them, exactly as if it had just arrived, and sends whatever answer it has.
Parameters
value(any) — A value asjson.decode()returns it.
Endpoint.feed()
rpc.Endpoint.feed(data: bytes)
Handles every message data completes, for a program that reads the
transport itself rather than through serve() or listen(), such as
one polling many connections. Empty data ends the connection, as an
empty read does.
Parameters
data(bytes) — The next bytes read from the transport.
Raises RpcFramingError when the stream cannot be read past a
message.
Endpoint.close()
rpc.Endpoint.close()
Closes the transport. Nothing more can be sent, and every request still
waiting is answered with an
RpcClosedError.
Endpoint.is_closed()
rpc.Endpoint.is_closed() -> bool
True once the endpoint is closed or the connection has ended.
Returns bool
Endpoint.to_string()
rpc.Endpoint.to_string() -> string
This endpoint as Endpoint(transport).
Returns string
2026, Richard Ore and Zuri contributors