文章目录
1. 创建项目
cargo new --lib grpc-demo
2. 配置proto
进入项目grpc-demo
2.1 配置Cargo.toml, 内容如下:
[package]
name = "grpc-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
tonic = "0.12.3"
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread", "full"] }
prost = "0.13.3"
[build-dependencies]
tonic-build = "0.11.0"
2.2 创建文件proto/hello.proto, 内容如下:
syntax = "proto3";
package hello;
service Hello {
rpc Hello(HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string data = 1;
string message = 2;
int32 code = 3;
}
2.3 添加build.rs文件, 内容如下:
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let protos = [
"proto/hello.proto",
];
tonic_build::configure().compile(&protos, &["proto/"])?;
Ok(())
}
2.4 项目结构如下:
2.5 编译proto文件
cargo build
3.0 处理服务
3.1 项目引入
编辑src/lib.rs, 内容如下:
pub mod hello {
tonic::include_proto!("hello");
}
3.2 添加src/server.rs, 内容如下:
HelloService 是实现hello的service
use tonic::{Request, Response, Status};
use tonic::transport::Server;
use grpc_demo::hello::{HelloRequest, HelloResponse};
use grpc_demo::hello::hello_server::{Hello, HelloServer};
#[derive(Default)]
pub struct HelloService {}
#[tonic::async_trait]
impl Hello for HelloService {
async fn hello(&self, req: Request<HelloRequest>) -> Result<Response<HelloResponse>, Status> {
println!("hello receive request: {:?}", req);
let response = HelloResponse {
data: format!("Hello, {}", req.into_inner().name),
message: "Ok".to_string(),
code: 200,
};
Ok(Response::new(response))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "0.0.0.0:50051".parse()?;
println!("server starting at: {}", addr);
Server::builder()
.add_service(HelloServer::new(HelloService::default()))
.serve(addr)
.await?;
Ok(())
}
3.3 添加src/client.rs, 内容如下:
HelloService 是实现hello的service
use tonic::Request;
use tonic::transport::Endpoint;
use grpc_demo::hello::hello_client::HelloClient;
use grpc_demo::hello::HelloRequest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = Endpoint::from_static("https://127.0.0.1:50051");
let mut hello_cli = HelloClient::connect(addr.clone()).await?;
let request = Request::new(HelloRequest {
name: "tonic".to_string(),
});
let response = hello_cli.hello(request).await?;
println!("hello response: {:?}", response.into_inner());
Ok(())
}
5 运行服务
5.1 修改Cargo.toml, 添加运行bin配置, 内容如下:
[package]
name = "grpc-demo"
version = "0.1.0"
edition = "2021"
[[bin]]
name="server"
path="src/server.rs"
[[bin]]
name="client"
path="src/client.rs"
[dependencies]
tonic = "0.12.3"
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread", "full"] }
prost = "0.13.3"
[build-dependencies]
tonic-build = "0.11.0"
5.2 运行server
cargo run --bin server
结果如下:
5.3 运行client, 测试
重新打开一个命令行, 进入项目根目录, 然后执行:
cargo run --bin client
结果如下: