Rust gRPC Demo

環境配置

  1. 首先要安裝Rust 環境 (省略安裝步驟)
  2. 安裝編譯依賴工具
我的系統是 Arch, 其他linux 系統的換一下包管理工具
sudo pacman -S autoconf automake libtool curl make g++ unzip
  1. 安裝 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  # 安裝成功
  1. 安装插件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 

posted on 2021-06-13 12:06  FraynJO  阅读(365)  评论(0)    收藏  举报

导航