Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! Example of using proc macro to generate working client and server.
use std::net::SocketAddr;
use futures_channel::oneshot;
use jsonrpsee::{ws_client::*, ws_server::WsServerBuilder};
mod rpc_impl {
use jsonrpsee::{proc_macros::rpc, types::async_trait, ws_server::SubscriptionSink};
#[rpc(client, server, namespace = "foo")]
pub trait Rpc {
#[method(name = "foo")]
async fn async_method(&self, param_a: u8, param_b: String) -> u16;
#[method(name = "bar")]
fn sync_method(&self) -> u16;
#[subscription(name = "sub", unsub = "unsub", item = String)]
fn sub(&self);
#[subscription(name = "echo", unsub = "no_more_echo", item = u32)]
fn sub_with_params(&self, val: u32);
}
pub struct RpcServerImpl;
#[async_trait]
impl RpcServer for RpcServerImpl {
async fn async_method(&self, _param_a: u8, _param_b: String) -> u16 {
42u16
}
fn sync_method(&self) -> u16 {
10u16
}
fn sub(&self, mut sink: SubscriptionSink) {
sink.send(&"Response_A").unwrap();
sink.send(&"Response_B").unwrap();
}
fn sub_with_params(&self, mut sink: SubscriptionSink, val: u32) {
sink.send(&val).unwrap();
sink.send(&val).unwrap();
}
}
}
// Use generated implementations of server and client.
use rpc_impl::{RpcClient, RpcServer, RpcServerImpl};
pub async fn websocket_server() -> SocketAddr {
let (server_started_tx, server_started_rx) = oneshot::channel();
std::thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().unwrap();
let mut server = rt.block_on(WsServerBuilder::default().build("127.0.0.1:0")).unwrap();
server.register_module(RpcServerImpl.into_rpc().unwrap()).unwrap();
rt.block_on(async move {
server_started_tx.send(server.local_addr().unwrap()).unwrap();
server.start().await
});
});
server_started_rx.await.unwrap()
}
#[tokio::test]
async fn proc_macros_generic_ws_client_api() {
let server_addr = websocket_server().await;
let server_url = format!("ws://{}", server_addr);
let client = WsClientBuilder::default().build(&server_url).await.unwrap();
assert_eq!(client.async_method(10, "a".into()).await.unwrap(), 42);
assert_eq!(client.sync_method().await.unwrap(), 10);
// Sub without params
let mut sub = client.sub().await.unwrap();
let first_recv = sub.next().await.unwrap();
assert_eq!(first_recv, Some("Response_A".to_string()));
let second_recv = sub.next().await.unwrap();
assert_eq!(second_recv, Some("Response_B".to_string()));
// Sub with params
let mut sub = client.sub_with_params(42).await.unwrap();
let first_recv = sub.next().await.unwrap();
assert_eq!(first_recv, Some(42));
let second_recv = sub.next().await.unwrap();
assert_eq!(second_recv, Some(42));
}