4个版本
0.2.1 | 2023年2月6日 |
---|---|
0.2.0 | 2022年9月20日 |
0.1.1 | 2021年4月10日 |
0.1.0 | 2021年4月9日 |
#13 in #bincode
53 每月下载量
用于 bonerjams-db
22KB
214 行
tonic-rpc
是一个宏,它从Rust定义而不是 proto
文件生成由 tonic
使用的特性和存根。
这意味着您可以在使用常规Rust类型的同时获得 tonic
的所有优势,而无需使用 proto
文件或构建脚本。当然,这会以互操作性为代价。
替代方案
tarpc
是一个定义服务为Rust特质的出色RPC库。
所需依赖项
tonic = "0.8.3"
tonic-rpc = { version = "0.2.1", features = [ <enabled-codecs> ] }
示例
定义服务为特质,而不是定义 proto
文件
#[tonic_rpc::tonic_rpc(json)]
trait Increment {
fn increment(arg: i32) -> i32;
}
属性 #[tonic_rpc(json)]
表示此服务将使用 json
序列化请求和响应。其他 编码
也可用。每个函数的参数和返回值必须实现 serde::Serialize
和 serde::Deserialize
。
可以通过定义一个 impl
来实现服务
struct State;
#[tonic::async_trait]
impl increment_server::Increment for State {
async fn increment(
&self,
request: tonic::Request<i32>,
) -> Result<tonic::Response<i32>, tonic::Status> {
Ok(tonic::Response::new(request.into_inner() + 1))
}
}
然后可以运行服务器和客户端
async fn run_client_server() {
let mut listener = tokio::net::TcpListener::bind("[::1]:0").await.unwrap();
let addr = listener.local_addr().unwrap();
tokio::spawn(async move {
tonic::transport::Server::builder()
.add_service(increment_server::IncrementServer::new(State))
.serve_with_incoming(tokio_stream::wrappers::TcpListenerStream::new(listener))
.await
});
let mut client = increment_client::IncrementClient::connect(format!("http://{}", addr))
.await
.unwrap();
let response = client.increment(32).await.unwrap().into_inner();
assert_eq!(33, response);
}
完整示例可在 此处 找到。更多示例可在 测试文件夹 中找到。
编码
可用于序列化RPC请求/响应类型的多个编解码器。每个编解码器都由一个 功能标志 启用。 必须启用这些功能之一。
bincode
- 使用bincode
cbor
- 使用serde_cbor
json
- 使用serde_json
messagepack
- 使用rmp-serde
例如,要使用 cbor
进行编码,请使用属性
#[tonic_rpc::tonic_rpc(cbor)]
并在 Cargo.toml
中包含
tonic-rpc = { version = "0.2.1", features = [ "cbor" ]}
。
流式传输
可以通过向服务特质的函数中添加属性 #[client_streaming]
或 #[server_streaming]
来在客户端或服务器端添加流式传输。这些属性的行为与在 proto
定义中添加 stream
关键字相同。
有关使用流式传输的示例,请参阅 测试文件夹。
请求/响应类型
tonic-rpc
生成的特性和函数将是修改了的方法的转换,这些方法在 tonic_rpc
特质中定义,并且已修改以添加对 gRPC
请求/响应类型、异步和流式传输的处理。
以下是签名转换的摘要
参数
fn f(x: X, y:Y) -> ..
变为
async fn f(&self, arg: tonic::Request<(X,Y)>) -> ..
返回值
fn f(..) -> Z
变为
async fn f(..) -> Result<tonic::Response<Z>, tonic::Status>
流式传输参数
#[client_streaming]
fn f(x:X) -> ..
变为
async fn f(&self, arg: tonic::Request<tonic::Streaming<X>>) -> ..
流式传输返回值
#[server_streaming]
fn f(..) -> Z
变为
type FStream: Stream<Item = Result<Z, tonic::Status>>;
async fn f(..) -> Result::<tonic::Response<Self::FStream>, tonic::Status>
依赖关系
~5.5–8MB
~142K SLoC