• rust学习-rpc


    使用框架rpcx-rs

    rpcx-rs 0.2.2 版本,使用Rust访问rpcx服务,支持 JSON 和 MessagePack 两种序列化方式。
    protobuf序列化的支持、服务治理各种功能(路由、失败处理、重试、熔断器、限流)、监控(metrics、trace)、注册中心(etcd、consul)等众多的功能

    cat ../Cargo.toml
    [package]
    name = "rust_demo4"
    version = "0.1.0"
    edition = "2021"
    
    [dependencies]
    rpcx = "0.2.2"
    serde = {
        version = "1.0", features = ["derive"] }
    serde_json = "1.0"
    rmp-serde = "1.1.2"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    // lib.rs
    use std::error::Error as StdError;
    
    use rmp_serde as rmps;
    use serde::{
       Deserialize, Serialize};
    
    use rpcx::*;
    
    #[derive(RpcxParam, Default, Debug, Copy, Clone, Serialize, Deserialize)]
    pub struct ArithAddArgs {
       
        #[serde(rename = "A")]
        pub a: u64,
        #[serde(rename = "B")]
        pub b: u64,
    }
    #[derive(RpcxParam, Default, Debug, Copy, Clone, Serialize, Deserialize)]
    pub struct ArithAddReply {
       
        #[serde(rename = "C")]
        pub c: u64,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    // main.rs
    use rust_demo4::{
       ArithAddArgs, ArithAddReply};
    use rpcx::*;
    
    fn test(args: ArithAddArgs) -> ArithAddReply {
       
        ArithAddReply {
        c: args.a + args.b }
    }
    
    fn main() {
       
    	// 第二个参数为 0,表示绑定所需的服务器线程数,如果设置为 0,则使用默认值(通常为 CPU 数量)
        let mut rpc_server = Server::new("0.0.0.0:8972".to_owned(), 0);
        // macro_rules! register_func {
       
        //     (
      	//        $rpc_server:expr, 
      	//        $service_path:expr, 
      	//        $service_method:expr, 
      	//        $service_fn:expr, 
      	//        $meta:expr, 
      	//        $arg_type:ty, 
      	//        $reply_type:ty
      	//     ) => { ... };
        // }
        register_func!(
            rpc_server,
            "Arith",      // service_path 服务名
            "Add",        // service_method 服务的方法
            test,         // service_fn 服务的函数名
            "".to_owned(),// meta
            ArithAddArgs, // 参数类型
            ArithAddReply // 响应类型
        );
    	
    	// pub fn get_fn(
        //     &self,
        //     service_path: String,
        //     service_method: String
    	// ) -> Option Result, Error>>
        let f = rpc_server
            .get_fn(String::from("Arith"), String::from("Add")) // service_path、service_method
            .unwrap(); // 返回 fn(_: &[u8], _: SerializeType) -> Result 或者 Error
        let s = String::from(r#"{"A":1,"B":2}"#);
        // 第一个参数是一个u8数组引用,即要传递的内容
        // 第二个参数是序列化类型
        let reply = f(s.as_ref(), SerializeType::JSON).unwrap();
        println!("reply:{}", String::from_utf8(reply).unwrap());
    }
    
    • 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

    service_path service_method service_fn

    服务端 —> service_path service_method service_fn 客户端 —> service_path service_method 请求参数

    • service_path
      服务的路径或名字,是一个字符串,用于标识服务
      多数情况下,服务端和客户端应该使用相同的服务路径来进行一次 RPC 调用
      当客户端发起远程调用请求时,需要指定所调用服务的 service_path
    • service_method
      服务的方法名,是一个字符串,用于标识服务中的方法
      同一服务中可能会有多个方法,为了区分不同的方法,需要使用不同的 service_method
      当客户端发起远程调用请求时,需要指定所调用服务的 service_method
    • service_fn
      指的是服务实际提供的函数或方法,它是一个可执行的代码片段,用于处理所接收到的请求并返回响应
      通常,RPC 库会将 service_fn 注册到服务端,并在客户端发起远程调用请求时将请求参数传递给它来处理

    学习rpcx示例

    框架

    tree -L 1 -C -F -I ".*"
    ./
    ├── Cargo.lock
    ├── Cargo.toml
    ├── LICENSE
    ├── README.md
    ├── build.rs
    ├── clippy.toml
    ├── examples/
    ├── rpcx/
    ├── rpcx_client/
    ├── rpcx_derive/
    ├── rpcx_protocol/
    ├── rpcx_server/
    ├── rustfmt.toml
    ├── target/
    └── test_suite/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    rpcx_server

    cat src/lib.rs
    use std::{
       
        boxed::Box,
        collections::HashMap,
        sync::{
       Arc, RwLock},
    };
    
    use std::net::SocketAddr;
    
    use rpcx_protocol::*;
    use std::{
       
        io::{
       BufReader, BufWriter, Write},
        net::{
       Shutdown, 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    【0116】PostgreSQL/MVCC
    C++是如何工作的
    [EFI]华硕 Asus VivoBook S510UA 电脑 Hackintosh 黑苹果efi引导文件
    【蓝桥杯选拔赛真题48】Scratch跳舞机游戏 少儿编程scratch蓝桥杯选拔赛真题讲解
    多表操作-外连接查询
    基于PHP+MySQL托管中心管理系统的设计与实现
    园子的新版 favicon,您觉得哪款更好看
    什么是缓存雪崩、击穿、穿透?
    【Node.JS】buffer类缓冲区
    Unity各版本的ndk与jdk对应关系
  • 原文地址:https://blog.csdn.net/wangkai6666/article/details/132531664