1 个不稳定版本
使用旧的 Rust 2015
0.1.1 | 2018年2月24日 |
---|---|
0.1.0 |
|
#27 in #early-stage
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.rs
和 echo_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