web-rpc
web-rpc is a crate for executing RPCs between browsing contexts, web workers, and channels. Similar to Google's tarpc, this crate allows you to define your RPC in code using trait syntax. This trait is consumed by a service macro,
which will generate everything that you need to implement RPC. Two notable features of this crate are that it supports bidirectional RPC over a single channel (e.g., between a Worker and a DedicatedWorkerGlobalScope) and posting/transferring Javascript types (e.g., OffscreenCanvas). The following is a simple example, see the crate documentation for a more complete explaination and more advanced examples.
The following code generates the RPC components using an attribute macro applied to a trait. It is recommended to put this RPC definition into some sort of shared crate that your modules can both access.
The code above will generate CalculatorClient, CalculatorService, and a new trait Calculator that you can use to implement a calculator as follows:
;
In the following example, we will use MessageChannel and MessagePort since they are easy to test and demonstrate the use of this crate inside a single module. A more interesting example however, is to use this crate to communicate between two browsing contexts or a Worker and a DedicatedWorkerGlobalScope. The following code defines the server:
let channel = new;
// note that interface::new is async and that both interfaces need to be polled in order to establish the connection between them
let = join.await;
// create a server with the first port
let server = new
.
.build;
// spawn the server
spawn_local;
To create a client:
// create a client using the second interface from above
let client = new
.
.build;
/* call `add` */
assert_eq!;
Features
- Bidirectional RPC over a single channel — both ends can be simultaneously client and server
- Posting and transferring JavaScript types via the
#[post(...)]and#[post(transfer(...))]attributes — types likeOffscreenCanvasorJsStringbypass serialization and are posted/transferred directly - Optional and fallible JavaScript types — posted types can be wrapped in
Option<JsType>orResult<JsOkType, JsErrType>for both arguments and return types.#[post(return)]on aResultposts both theOkandErrvariants - Streaming RPCs — methods returning
impl Stream<Item = T>stream items to the client, with support for abort-on-drop, close-and-drain, and#[post(return)] - Async and sync methods — async server methods run concurrently with per-request cancellation
- Notifications — methods with no return type are fire-and-forget
- Borrowed parameters —
&strand&[u8]are deserialized zero-copy on the server
For more advanced examples, check out the crate documentation. Need help with your latest project? Get in touch via contact@allwright.io and tell me about what you are working on - I am a available for new assignments.