rpcx microservice framework in Rust

Overview

rpcx-rs

Build Status Crate API

Rust library for rpcx rpc/microservice framework.

Use the simplest style to explore Rust function as cross-platform rpc services.

If you can write Rust functions, you can write rpc services. It is so easy.

see all exampes: rpcx-rs-examples.

Roadmap

0.1.x

protocol and client/server lib.

  • Protocol
  • Client (call synchronous/asynchronous)
  • support JSON, MessagePack and Protobuf
  • Service implementation

0.2.x

  • Service discovery
    • static multiple peers
    • etcd
    • consul
  • service governance
  • Select Mode
    • RandomSelect,
    • RoundRobin
    • WeightedRoundRobin
    • WeightedICMP
    • ConsistentHash
    • Closest
    • Custiomized
  • Faile Mode
    • Failover
    • Failfast
    • Failtry

0.3.x

  • plugins
  • document
  • unit tests and integration tests
  • other features like implementation in Go

Usage

Add this to your Cargo.toml:

[dependencies]
rpcx = "0.2.0"

Example

Write the Argument and the Reply

First you should write the argument and the reply. They are used by rpc services and clients.

use std::error::Error as StdError;

use rmp_serde as rmps; 
use serde::{Deserialize, Serialize};

use rpcx_derive::*;
use rpcx_protocol::{Error, ErrorKind, Result, RpcxParam, SerializeType};

#[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,
}

You must add RpcxParamSerializeDeserialize and Default traits in derive. Rpcx can add hepler methods for serialization.

If not, you need to implement RpcxParam and Default mannually.

Here we defined ArithAddArgs as the argument type and ArithAddReply as the reply type.

Implement the server

use mul_model::{ArithAddArgs, ArithAddReply};
use rpcx::*;

fn add(args: ArithAddArgs) -> ArithAddReply {
    ArithAddReply { c: args.a + args.b }
}

fn mul(args: ArithAddArgs) -> ArithAddReply {
    ArithAddReply { c: args.a * args.b }
}

fn main() {
    let mut rpc_server = Server::new("127.0.0.1:8972".to_owned());
    register_func!(
        rpc_server,
        "Arith",
        "Add",
        add,
        ArithAddArgs,
        ArithAddReply
    );

    register_func!(
        rpc_server,
        "Arith",
        "Mul",
        mul,
        ArithAddArgs,
        ArithAddReply
    );

    rpc_server.start().unwrap();
}

Here we implement two services: add and mul. And we use register_func! macro to register them with their expored names(service_path and service_method). Clients can use the name to access them.

Implement client

Here we use one client to access Arith.Mul service in a loop.

use std::collections::hash_map::HashMap;

use mul_model::*;
use rpcx::Client;
use rpcx::{Result, SerializeType};

pub fn main() {
    let mut c: Client = Client::new("127.0.0.1:8972");
    c.start().map_err(|err| println!("{}", err)).unwrap();
    c.opt.serialize_type = SerializeType::JSON;

    let mut a = 1;
    loop {
        let service_path = String::from("Arith");
        let service_method = String::from("Mul");
        let metadata = HashMap::new();
        let args = ArithAddArgs { a: a, b: 10 };
        a += 1;

        let reply: Option<Result<ArithAddReply>> =
            c.call(service_path, service_method, false, metadata, &args);
        match reply {
            Some(Ok(r)) => println!("received: {:?}", r),
            Some(Err(err)) => println!("received err:{}", err),
            None => {}
        }
    }
}

Actually you can use this client to access rpcx services implemented by other program languages such as service in go.

As you see, only after three steps you have expored Rust functions (add and mul) as rpc services.

You can find more examples at rpcx-rs/examples

License

rpcx-rs is distributed under the terms of both the MIT license.

See LICENSE-APACHE and LICENSE-MIT, and COPYRIGHT for details.

You might also like...
No-nonsense, elegant request framework

Note: this crate is in an experimental sketch state. Please be careful if using on production environments. nerf nerf stands for: No-nonsense: Correct

Grow Rust is a Growtopia Private Server made in Rust

Grow Rust is a Growtopia Private Server made in Rust

Multiplex server for rust-analyzer, allows multiple LSP clients (editor windows) to share a single rust-analyzer instance per cargo workspace

ra-multiplex   Multiplex server for rust-analyzer, allows multiple LSP clients (editor windows) to share a single rust-analyzer instance per cargo wor

DNS Server written in Rust for fun, see https://dev.to/xfbs/writing-a-dns-server-in-rust-1gpn

DNS Fun Ever wondered how you can write a DNS server in Rust? No? Well, too bad, I'm telling you anyways. But don't worry, this is going to be a fun o

Rust crate for configurable parallel web crawling, designed to crawl for content

url-crawler A configurable parallel web crawler, designed to crawl a website for content. Changelog Docs.rs Example extern crate url_crawler; use std:

Rust crate for scraping URLs from HTML pages

url-scraper Rust crate for scraping URLs from HTML pages. Example extern crate url_scraper; use url_scraper::UrlScraper; fn main() { let director

FTP client for Rust

rust-ftp FTP client for Rust Documentation rust-ftp Installation Usage License Contribution Development environment Installation FTPS support is achie

The gRPC library for Rust built on C Core library and futures

gRPC-rs gRPC-rs is a Rust wrapper of gRPC Core. gRPC is a high performance, open source universal RPC framework that puts mobile and HTTP/2 first. Sta

A library to work with CIDRs in rust

ipnetwork This is a library to work with IPv4 and IPv6 CIDRs in Rust Run Clippy by doing rustup component add clippy cargo clippy Installation This c

Comments
  • 关于register_func! 注册一个对象的方法有什么办法吗?

    关于register_func! 注册一个对象的方法有什么办法吗?

    我想注册

        register_func!(
            rpc_server,
            RPC_PS_Path,
            RPC_PS_Write,
            write,
            "".to_owned(),
            WriteRequest,
            WriteResponse
        );
    

    如果方法绑定在对象上 如

    struct AAA{
    }
    
    impl AAA{
        pub fn write(req) -> rep {}
    }
    
    
     register_func!(
            rpc_server,
            RPC_PS_Path,
            RPC_PS_Write,
            AAA.write,
            "".to_owned(),
            WriteRequest,
            WriteResponse
        );
    
    

    不行的。

    然后我用闭包

    let write = |x: WriteRequest| -> WriteResponse {
            let rep: WriteResponse = Default::default();
            rep
        };
    
     register_func!(
            rpc_server,
            RPC_PS_Path,
            RPC_PS_Write,
            write,
            "".to_owned(),
            WriteRequest,
            WriteResponse
        );
    
    

    还是不工作,这个问题该如何处理呀?谢谢

    opened by ansjsun 2
  • rpc server 优雅的关闭方式

    rpc server 优雅的关闭方式

    根据 Server::start 的函数签名:

    pub fn start(&mut self) -> Result<()>
    

    可以看到这里使用的是可变借用。该函数一旦执行将一直阻塞,直到 listen 用 fd 被关闭。 而这个 fd 只会在 Server::close 函数中被关闭,以下是它的函数签名:

    pub fn close(&self)
    

    可以看到这里有一个不可变借用。

    由于 Rust 语言限制同一个变量的可变借用和不可变借用不能同时存在,因此在调用 start 函数之后,无法再调用 close 函数将其关闭。 请问有无优雅的方式来将正在监听的 RPC Server 关闭?

    opened by Kiprey 0
Owner
smallnest
Author of 《Scala Collections Cookbook》
smallnest
Implementing Bendersnatch curve using Arkwork's framework in Rust.

This is a reference implementation of Bendersnatch curve using Arkwork's framework in Rust. The spec of the curve is available here. There was also a Python reference implementation here.

zhenfei 8 Jun 18, 2022
Rust implementation of PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols

Rust PRECIS Framework libray PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols as descr

Santiago Carot-Nemesio 1 Oct 20, 2022
High performance I/O framework written by Rust inspired by Netty

Introduction Retty is a High performance I/O framework written by Rust inspired by Netty 基于mio的IO多路复用高并发、高性能网络通信开发框架 Feature Rayon 线程池包装 EventLoop / E

lgphp 9 Dec 25, 2022
Volo is a high-performance and strong-extensibility Rust RPC framework that helps developers build microservices.

Volo is a high-performance and strong-extensibility Rust RPC framework that helps developers build microservices.

CloudWeGo 1.3k Jan 2, 2023
A simple message based networking library for the bevy framework

Spicy Networking for Bevy bevy_spicy_networking is a solution to the "How do I connect multiple clients to a single server" problem in your bevy games

Cabbit Studios 67 Jan 1, 2023
axum-server is a hyper server implementation designed to be used with axum framework.

axum-server axum-server is a hyper server implementation designed to be used with axum framework. Features Conveniently bind to any number of addresse

null 79 Jan 4, 2023
Fullstack development framework for UTXO-based dapps on Nervos Network

Trampoline-rs The framework for building powerful dApps on the number one UTXO chain, Nervos Network CKB. This is an early-stage, currently very incom

TannrA 2 Mar 25, 2022
A versatile and efficient proxy framework with nice features suitable for various use cases.

A versatile and efficient proxy framework with nice features suitable for various use cases.

null 1.7k Jan 9, 2023
Astar Network is an interoperable blockchain based the Substrate framework and the hub for dApps within the Polkadot Ecosystem

Astar Network is an interoperable blockchain based the Substrate framework and the hub for dApps within the Polkadot Ecosystem. With Astar Network and

Astar Network (Plasm) 43 Dec 14, 2022
Drpc-Correct, high performance, robust, easy use Remote invocation framework

Drpc - Correct, high performance, robust, easy use Remote invocation framework

darkrpc 30 Dec 17, 2022