#rpc #rpc-service #client-server #macro #marpc

过程宏 marpc-macros

marpc 的 #[rpc] 宏实现

2 个不稳定版本

0.2.0 2023年10月3日
0.1.0 2023年7月29日

17#rpc-service

每月 下载 23
用于 marpc

MIT/Apache 许可证

14KB
277

MARPC - 基于宏的、无样板代码的 rpc 库

crates.io docs.rs license MIT or Apache 2.0

API 文档

这是一个简单的 rpc 库,灵感来自 server_fn,它是 leptos 生态系统的一部分。它允许你定义将在服务器上运行但由客户端调用的函数。主要用例是带有 Rust 前端的 web 应用程序,但该库设计得易于适配,不对传输协议或序列化格式施加任何限制。

[dependencies]
marpc = "0.2.0"

功能

  • 在一个地方定义函数,从客户端调用它们并在服务器上执行。
  • 无样板代码。Rpc 在一个地方定义,功能标志控制是否为客户端、服务器或两者生成代码。
  • "使用自己的传输"。在客户端使用 ClientRpcService::handle,在服务器上使用 handle_rpc 来控制 rpc 调用如何到达服务器以及如何返回响应。
  • "使用自己的(反)序列化器"。你可以为你的 rpc 调用使用任何类型的(反)序列化器。marpc 还定义了一个简单的 json 格式,你可以使用。

示例

首先定义一个 rpc 服务

struct Service;

impl marpc::RpcService for Service {
    type Format = marpc::Json;
}

#[cfg(feature = "client")]
impl marpc::ClientRpcService for Service {
    type ClientError = Box<dyn std::error::Error>;

    fn handle<'a>(
        uri: &'static str,
        payload: &'a [u8],
    ) -> Pin<Box<dyn 'a + Future<Output = Result<Vec<u8>, Self::ClientError>>>> {
        // Send payload to the server
    }
}

#[cfg(feature = "server")]
marpc::register_service!(Service);

使用以下方式定义 rpc 函数

#[marpc::rpc(AddRpc, uri = "/api/add", service = Service)]
async fn add(a: i32, b: i32) -> Result<i32, ()> {
    Ok(a + b)
}

然后在客户端调用它们

add(5, 6).await;

在服务器上,你可以使用以下方式处理 rpc 调用

marpc::handle_rpc::<Service>(uri, (), payload).await

有关一个简单的示例,请参阅 examples/add.rs,其中两个线程通过全局队列进行通信。请注意,必须使用 --all-features--features client,server 编译,因为客户端和服务器代码都需要生成。

请参阅examples/hello_net.rs以获取一个更复杂的示例,其中包括客户端和服务器通过tcp流进行通信。在一个窗口中运行cargo run --features server --example hello_net -- server Hello,然后在另一个窗口中运行cargo run --features client --example hello_net -- client world

许可证

此库采用MIT许可证和Apache License 2.0双许可。自行选择使用的许可证。请参阅LICENSE-MITLICENSE-APACHE

依赖项

~300–760KB
~18K SLoC