Rust gRPC Demo
環境配置
- 首先要安裝Rust 環境 (省略安裝步驟)
- 安裝編譯依賴工具
我的系統是 Arch, 其他linux 系統的換一下包管理工具
sudo pacman -S autoconf automake libtool curl make g++ unzip
- 安裝 protoc
git clone https://github.com/google/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
./configure #By default, the package will be installed to /usr/local
make
make check
sudo make install
sudo ldconfig
驗證
protoc --version
-> libprotoc 3.17.2 # 安裝成功
- 安装插件protoc-gen-rust和protoc-gen-rust-grpc
cargo install protobuf
cargo install grpc-compiler
項目目錄結構
./grpc-demo/
├── build.rs
├── Cargo.lock
├── Cargo.toml
├── hello.proto
├── src
│ ├── bin
│ │ ├── client.rs
│ │ └── server.rs
│ ├── hello_grpc.rs
│ ├── hello.rs
│ └── lib.rs
cargo 新建一個項目
cargo new grpc-demo
配置 Cargo.toml
[package]
name = "grpc-demo"
version = "0.1.0"
authors = ["fraynjo <>"]
edition = "2018"
build = "build.rs"
[dependencies]
protobuf = "2"
grpc = "0.8.3"
grpc-protobuf = "0.8.3"
futures = "0.3.15"
[build-dependencies]
protoc-rust-grpc = "0.8.3"
grpc-demo/build.rs
extern crate protoc_rust_grpc;
fn main() {
protoc_rust_grpc::Codegen::new()
.out_dir("src")
.input("hello.proto")
.rust_protobuf(true)
.run()
.expect("protoc-rust-grpc");
}
grpc-demo/hello.proto
syntax = "proto3";
package hello;
service HelloService {
rpc say(SayRequest) returns (SayResponse);
}
message SayRequest {
string name = 1;
}
message SayResponse {
string msg = 1;
}
根據.proto文件编译生成Rust代码
項目根目錄執行
cargo build
生成2個文件
src/hello.rs
src/hello_grpc.rs
grpc-demo/src/lib.rs
pub mod hello;
pub mod hello_grpc;
服務端代碼 grpc-demo/src/bin/server.rs
use std::thread;
use grpc_demo::hello_grpc::*;
use grpc_demo::hello::*;
struct HelloServer;
impl HelloService for HelloServer {
fn say(&self,
_o: grpc::ServerHandlerContext,
req: grpc::ServerRequestSingle<SayRequest>,
resp: grpc::ServerResponseUnarySink<SayResponse>) -> grpc::Result<()> {
let mut r = SayResponse::new();
println!("Say {}", req.message.get_name());
r.set_msg("Success".to_string());
resp.finish(r)
}
}
fn main() {
let mut server = grpc::ServerBuilder::new_plain();
server.http.set_port(10086);
server.add_service(HelloServiceServer::new_service_def(HelloServer));
let _server = server.build().expect("Could not start server");
loop {
thread::park();
}
}
客戶段代碼 grpc-demo/src/bin/client.rs
use grpc_demo::hello::*;
use grpc_demo::hello_grpc::*;
use futures::executor;
use grpc::ClientStubExt;
fn main() {
let client = HelloServiceClient::new_plain("127.0.0.1", 10086, Default::default()).unwrap();
let mut req = SayRequest::new();
req.set_name("FraynJo".to_string());
let resp = client.say(grpc::RequestOptions::new(), req).join_metadata_result();
let resp = executor::block_on(resp);
match resp {
Err(e) => panic!("{:?}", e),
Ok((_, r, _)) => println!("{:?}", r),
}
}
編譯運行
cargo build
grpc-demo/target/debug/ 下生成 server 和 client 執行文件
分別執行 server 和 client