81 个版本

0.19.2 2024 年 6 月 1 日
0.19.0 2024 年 1 月 14 日
0.18.0 2023 年 9 月 4 日
0.17.0 2023 年 5 月 8 日
0.0.3 2014 年 11 月 23 日

#33网络编程

Download history 24489/week @ 2024-05-03 23750/week @ 2024-05-10 41123/week @ 2024-05-17 35195/week @ 2024-05-24 40397/week @ 2024-05-31 41424/week @ 2024-06-07 39259/week @ 2024-06-14 41813/week @ 2024-06-21 34679/week @ 2024-06-28 20356/week @ 2024-07-05 18717/week @ 2024-07-12 16888/week @ 2024-07-19 16980/week @ 2024-07-26 16099/week @ 2024-08-02 18995/week @ 2024-08-09 16659/week @ 2024-08-16

72,222 每月下载量
用于 37 个 crate (16 直接)

MIT 许可证

2MB
42K SLoC

capnp-rpc-rust

crates.io

文档

这是 Cap'n Proto 远程过程调用协议的 一级 实现。它是原始 C++ 实现 的相当直接的翻译。

定义接口

首先,确保您的系统上已安装 capnp 可执行文件,并且您在 Cargo.tomlbuild-dependencies 部分中包含 capnpc crate。然后,在一个名为 foo.capnp 的文件中,定义您的接口

@0xa7ed6c5c8a98ca40;

interface Bar {
    baz @0 (x :Int32) -> (y :Int32);
}

interface Qux {
    quux @0 (bar :Bar) -> (y :Int32);
}

现在您可以在 build.rs 文件中调用模式编译器,如下所示

fn main() {
    ::capnpc::CompilerCommand::new().file("foo.capnp").run().unwrap();
}

您可以将生成的代码包含到项目中,如下所示

pub mod foo_capnp {
  include!(concat!(env!("OUT_DIR"), "/foo_capnp.rs"));
}

调用 RPC 对象上的方法

对于每个定义的接口,生成的代码都包含一个可以用来调用接口方法的 Client 结构。例如,以下代码调用了 Bar.baz() 方法

fn call_bar(client: ::foo_capnp::bar::Client)
   -> Box<Future<Item=i32, Error=::capnp::Error>>
{
    let mut req = client.baz_request();
    req.get().set_x(11);
    Box::new(req.send().promise.and_then(|response| {
         Ok(response.get()?.get_y())
    }))
}

bar::Client 是对可能远程的 Bar 对象的引用。Cap'n Proto RPC 运行时跟踪任何给定时间点此类引用的数量,并在没有此类引用时自动释放对象。

实现接口

生成的代码还包括每个接口的 Server 特性。要创建一个具有 RPC 功能的对象,您必须实现该特性。

struct MyBar {}

impl ::foo_capnp::bar::Server for MyBar {
     fn baz(&mut self,
            params: ::foo_capnp::bar::BazParams,
            mut results: ::foo_capnp::bar::BazResults)
        -> Promise<(), ::capnp::Error>
     {
         // `pry!` is defined in capnp_rpc. It's analogous to `try!`.
         results.get().set_y(pry!(params.get()).get_x() + 1);

         Promise::ok(())
     }
}

然后你可以将你的对象转换为能力客户端,如下所示

let client: foo_capnp::bar::Client = capnp_rpc::new_client(MyBar {});

这个新的 client 现在可以跨网络传输。当你构建一个 RpcSystem 时,你可以将其用作引导能力,你还可以将其作为 RPC 方法参数和结果传递。

异步方法

生成的 Server 特性的方法返回类型为 Promise<<(), ::capnp::Error> 的值。一个 Promise 要么是一个立即值,由 Promise::ok()Promise::err() 构造,或者它是一个由 Promise::from_future() 构造的 Future 的包装器。一旦发生两件事,结果就会发送回方法调用者

  1. 已删除 Results 结构。
  2. 返回的 Promise 已解析。

通常(1)发生在(2)之前。

以下是一个不立即返回的方法实现示例

struct MyQux {}

impl ::foo_capnp::qux::Server for MyQux {
     fn quux(&mut self,
             params: ::foo_capnp::qux::QuuxParams,
             mut results: ::foo_capnp::wux::QuuxResults)
        -> Promise<(), ::capnp::Error>
     {
         // Call `baz()` on the passed-in client.

         let bar_client = pry!(pry!(params.get()).get_bar());
         let mut req = bar_client.baz_request();
         req.get().set_x(42);
         Promise::from_future(req.send().promise.and_then(move |response| {
             results.get().set_y(response.get()?.get_y());
             Ok(())
         }))
     }
}

同一对象上的多个 quux 调用可以同时激活,并且它们不需要按调用的顺序返回。

进一步阅读

依赖项

~0.8–1.1MB
~20K SLoC