Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/allsey87/web-rpc

Bi-directional RPC for the Web
https://github.com/allsey87/web-rpc

Last synced: 24 days ago
JSON representation

Bi-directional RPC for the Web

Awesome Lists containing this project

README

        

[![CI](https://github.com/allsey87/web-rpc/actions/workflows/test.yaml/badge.svg)](https://github.com/allsey87/web-rpc/actions)
[![Crates.io](https://img.shields.io/crates/v/web-rpc.svg)](https://crates.io/crates/web-rpc)
[![api-docs](https://docs.rs/web-rpc/badge.svg)](https://docs.rs/web-rpc/)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

# web-rpc
`web-rpc` is a crate for executing RPCs between browsing contexts, web workers, and channels. Similar to Google's [tarpc](https://github.com/google/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](https://docs.rs/web-sys/latest/web_sys/struct.Worker.html) and a [DedicatedWorkerGlobalScope](https://docs.rs/web-sys/latest/web_sys/struct.DedicatedWorkerGlobalScope.html)) and posting/transferring Javascript types (e.g., [OffscreenCanvas](https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html)). The following is a simple example, see the [crate documentation](https://docs.rs/web-rpc/latest/web_rpc/) 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.
```rust
#[web_rpc::service]
pub trait Calculator {
fn add(left: u32, right: u32) -> u32;
}
```
The code above will generate `CalculatorClient`, `CalculatorService`, and a new trait `Calculator` that you can use to implement a calculator as follows:
```rust
struct CalculatorServiceImpl;

impl Calculator for CalculatorServiceImpl {
fn add(&self, left: u32, right: u32) -> u32 {
left + right
}
}
```
In the following example, we will use [MessageChannel](https://docs.rs/web-sys/latest/web_sys/struct.MessageChannel.html) and [MessagePort](https://docs.rs/web-sys/latest/web_sys/struct.MessagePort.html) 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](https://docs.rs/web-sys/latest/web_sys/struct.Worker.html) and a [DedicatedWorkerGlobalScope](https://docs.rs/web-sys/latest/web_sys/struct.DedicatedWorkerGlobalScope.html). The following code defines the server:
```rust
let channel = web_sys::MessageChannel::new();
// note that interface::new is async and that both interfaces need to be polled in order to establish the connection between them
let (server_interface, client_interface) = futures_util::future::join(
web_rpc::Interface::new(channel.port1()),
web_rpc::Interface::new(channel.port2()),
).await;
// create a server with the first port
let server = web_rpc::Builder::new(server_interface)
.with_service::>(CalculatorServiceImpl)
.build();
// spawn the server
wasm_bindgen_futures::spawn_local(server);
```
To create a client:
```rust
// create a client using the second interface from above
let client = web_rpc::Builder::new(client_interface)
.with_client::()
.build();
/* call `add` */
assert_eq!(client.add(41, 1).await, 42);
```

For more advanced examples, check out the [crate documentation](https://docs.rs/web-rpc/latest/web_rpc/). Need help with your latest project? Get in touch via [[email protected]](mailto:[email protected]) and tell me about what you are working on — I am a freelance software engineer.