Skip to content

allsey87/web-rpc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CI Crates.io api-docs MIT licensed

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.

#[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:

struct CalculatorServiceImpl;

impl Calculator for CalculatorServiceImpl {
    fn add(&self, left: u32, right: u32) -> u32 {
        left + right
    }
}

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 = 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::<CalculatorService<_>>(CalculatorServiceImpl)
    .build();
// spawn the server
wasm_bindgen_futures::spawn_local(server);

To create a client:

// create a client using the second interface from above
let client = web_rpc::Builder::new(client_interface)
    .with_client::<CalculatorClient>()
    .build();
/* call `add` */
assert_eq!(client.add(41, 1).await, 42);

For more advanced examples, check out the crate documentation. Need help with your latest project? Get in touch via [email protected] and tell me about what you are working on — I am a freelance software engineer.

About

Bi-directional RPC for the Web

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages