1 个不稳定版本

使用旧的 Rust 2015

0.1.1 2018年2月24日
0.1.0 2018年2月23日

#27 in #early-stage

MIT/Apache

125KB
3K SLoC

Rust RPC 框架

copra 是一个旨在易于使用和配置的 RPC 框架。它可以生成服务器和客户端的大部分样板代码。您只需要实现服务的核心逻辑。

安装

协议编译器安装

copra 使用 Protocol Buffers (又称 protobuf) 来交换消息和描述服务签名。消息和服务描述编写在 .proto 文件中,copra 依赖于协议编译器从这些文件生成 rust 代码。

访问 此网站 并下载 proto-3.*-your-arch.zip (copra 需要协议版本 3),将 protoc 可执行文件提取到您喜欢的文件夹中,然后将其添加到您的 PATH

Cargo 设置

将此添加到您的 Cargo.toml

[dependencies]
copra = "0.1"
futures = "0.1"
tokio-core = "0.1"

[build-dependencies]
protoc-rust-copra = "0.1"

示例

以下是一个实现 echo RPC 的示例。首先,创建一个名为 echo.proto 的文件,并将其放置在清单目录中(即与 Cargo.toml 相邻)。填写如下

syntax = "proto3"

message EchoMessage {
    string msg = 1;
}

// Our echo service contains two method. One is sending back the original string
// directly, and the other is returning the string in reversed form.
service Echo {
    rpc echo(EchoMessage) returns (EchoMessage);
    rpc reverse_echo(EchoMessage) returns (EchoMessage);
}

然后,在清单目录中创建一个 build.rs,并添加以下内容

extern crate protoc_rust_copra;

fn main() {
    protoc_rust_copra::run(protoc_rust_copra::Args {
        out_dir: "src/protos",
        input: &["echo.proto"],
        includes: &[],
        rust_protobuf: true
    }).expect("Failed to compile proto files");
}

这将生成 echo.rsecho_copra.rs 文件,位于 src/protos

然后,将以下内容添加到 main.rs

extern crate copra;
extern crate futures;
extern crate tokio_core;

use copra::{ChannelBuilder, Controller, MethodError, ServerBuilder, ServiceRegistry};
use futures::future::{self, Future, FutureResult};
use std::thread;
use tokio_core::reactor::Core;

use protos::echo::EchoMessage;
use protos::echo_copra::{EchoRegistrant, EchoService, EchoStub};

mod protos;

// Service provider must implement Clone
#[derive(Clone)]
struct Echo;

// EchoService is a trait for defining service logic
// It is generated by protoc-rust-copra
impl EchoService for Echo {
    type EchoFuture = FutureResult<(EchoMessage, Controller), MethodError>;

    type ReverseEchoFuture = FutureResult<(EchoMessage, Controller), MethodError>;

    fn echo(&self, (req, ctrl): (EchoMessage, Controller)) -> Self::EchoFuture {
        let mut response = EchoMessage::new();
        response.set_msg(req.msg);
        future::ok((response, ctrl))
    }

    fn reverse_echo(
        &self,
        (req, ctrl): (EchoMessage, Controller)
    ) -> Self::ReverseEchoFuture {
        let rev: String = req.msg.chars().rev().collect();
        let mut response = EchoMessage::new();
        response.set_msg(rev);
        future::ok((response, ctrl))
    }
}

fn main() {
    let addr = "127.0.0.1:8989";

    // server side
    thread::spawn(move || {
        // register the service provider, so that it can be accessed
        let registrant = EchoRegistrant::new(Echo);
        let mut registry = ServiceRegistry::new();
        registry.register_service(registrant);

        let server = ServerBuilder::new(addr, registry).build().unwrap();
        server.start();
    });

    // client side
    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let channel = core.run(ChannelBuilder::single_server(addr, handle).build())
        .unwrap();
    let stub = EchoStub::new(&channel);

    let mut request = EchoMessage::new();
    request.set_msg("Hello world".to_string());

    let (response, _info) = core.run(stub.echo(request.clone())).unwrap();
    println!("{}", response.msg);

    let (response, _info) = core.run(stub.reverse_echo(request)).unwrap();
    println!("{}", response.msg);
}

最后,通过执行以下命令构建和运行此示例

$ cargo build
$ cargo run

注意

该项目仍处于早期开发阶段。它基本可用,但您应谨慎使用。

依赖关系

~9.5MB
~184K SLoC