|
3 | 3 |
|
4 | 4 | [](https://crates.io/crates/jrpc2) |
5 | 5 |
|
6 | | -A JSON-RPC 2.0 client/server library in rust. |
| 6 | +A JSON-RPC 2.0 client/server library in rust. |
| 7 | + |
| 8 | + |
| 9 | +# How to use |
| 10 | + |
| 11 | +## Define the structed value types |
| 12 | + |
| 13 | +You should define the types of the follwing three structed values: |
| 14 | + |
| 15 | + - Request Parameters [Reference](https://www.jsonrpc.org/specification#parameter_structures) |
| 16 | + - Response Result [Reference](https://www.jsonrpc.org/specification#response_object) |
| 17 | + - Error Data [Reference](https://www.jsonrpc.org/specification#error_object) |
| 18 | + |
| 19 | +For example: |
| 20 | + |
| 21 | + type RequestParams = Vec<u32>; |
| 22 | + type ResponseResult = u32; |
| 23 | + type ErrorData = String; |
| 24 | + |
| 25 | +## Define the handler |
| 26 | + |
| 27 | + You should implement the THandler trait to define the server side logic: |
| 28 | + |
| 29 | + #[async_trait] |
| 30 | + pub trait THandler<S, R, E> |
| 31 | + where |
| 32 | + S: Serialize, |
| 33 | + { |
| 34 | + async fn handle(&self, conn: Arc<JsonRpc2<S, R, E>>, request: Request<S>); |
| 35 | + } |
| 36 | + |
| 37 | + For example: |
| 38 | + |
| 39 | + struct Add {} |
| 40 | + |
| 41 | + #[async_trait] |
| 42 | + impl THandler<RequestParams, ResponseResult, ErrorData> for Add { |
| 43 | + async fn handle( |
| 44 | + &self, |
| 45 | + json_rpc2: Arc<JsonRpc2<RequestParams, ResponseResult, ErrorData>>, |
| 46 | + request: Request<RequestParams>, |
| 47 | + ) { |
| 48 | + match request.method.as_str() { |
| 49 | + "add" => { |
| 50 | + let params = request.params.unwrap(); |
| 51 | + let add_res: u32 = params.iter().sum(); |
| 52 | + let response = Response::new(request.id.unwrap(), Some(add_res), None); |
| 53 | + json_rpc2.response(response).unwrap(); |
| 54 | + } |
| 55 | + |
| 56 | + _ => { |
| 57 | + log::info!("unknow method"); |
| 58 | + } |
| 59 | + } |
| 60 | + } |
| 61 | + } |
| 62 | + |
| 63 | +## Init JSON-RPC server |
| 64 | + |
| 65 | + let addr = "127.0.0.1:9002"; |
| 66 | + let listener = TcpListener::bind(&addr).await.expect("Can't listen"); |
| 67 | + |
| 68 | + if let Ok((stream, _)) = listener.accept().await { |
| 69 | + let server_stream = ServerObjectStream::accept(stream) |
| 70 | + .await |
| 71 | + .expect("cannot generate object stream"); |
| 72 | + JsonRpc2::new(Box::new(server_stream), Some(Box::new(Add {}))).await; |
| 73 | + } |
| 74 | + |
| 75 | +## Init JSON-RPC client |
| 76 | + |
| 77 | + let url = url::Url::parse("ws://127.0.0.1:9002/").unwrap(); |
| 78 | + let client_stream = ClientObjectStream::connect(url) |
| 79 | + .await |
| 80 | + .expect("cannot generate object stream"); |
| 81 | + |
| 82 | + let conn_arc = |
| 83 | + JsonRpc2::<_, ResponseResult, ErrorData>::new(Box::new(client_stream), None).await; |
| 84 | + |
| 85 | +## Call the function |
| 86 | + |
| 87 | + match conn_arc.call("add", Some(vec![2u32, 3u32, 4u32])).await { |
| 88 | + Ok(response) => { |
| 89 | + let result = response.result.unwrap(); |
| 90 | + assert_eq!(result, 9); |
| 91 | + } |
| 92 | + Err(err) => { |
| 93 | + log::error!("call add error: {}", err); |
| 94 | + } |
| 95 | + } |
| 96 | + |
0 commit comments