tonic 使用记录

2 minute read Published: 2022-05-20

本文代码

服务端

cargo run --bin server

客户端

cargo run --bin client <message>...

Cargo.toml

[package]
name = "tonic-record"
version = "0.1.0"
authors = ["Li Lei <this.lilei@gmail.com>"]
edition = "2021"

[[bin]]
name = "server"
path = "src/server.rs"

[[bin]]
name = "client"
path = "src/client.rs"

[dependencies]
anyhow = "1.0.57"
tonic = "0.7.2"
prost = "0.10.3"
tokio = { version = "1.18.2", features = ["macros", "rt-multi-thread"] }

[build-dependencies]
tonic-build = "0.7.2"

proto/echo.proto

syntax = "proto3";

package echo_package;

message Text {
  string content = 1;
}

service EchoService {
  rpc EchoText(Text) returns (Text);
}

build.rs

use std::io;

fn main() -> io::Result<()> {
    tonic_build::compile_protos("proto/echo.proto")?;
    Ok(())
}

src/proto.rs

pub mod echo {
    tonic::include_proto!("echo_package");
}

src/server.rs

mod proto;

use tonic::{async_trait, transport::Server, Request, Response, Status};

use proto::echo::{
    echo_service_server::{EchoService, EchoServiceServer},
    Text,
};

struct Service;

#[async_trait]
impl EchoService for Service {
    async fn echo_text(&self, request: Request<Text>) -> Result<Response<Text>, Status> {
        let content = &request.get_ref().content;
        println!("{}", content);
        Ok(Response::new(Text {
            content: format!("[{}]", content),
        }))
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    Server::builder()
        .add_service(EchoServiceServer::new(Service))
        .serve("[::1]:8080".parse()?)
        .await?;
    Ok(())
}

src/client.rs

mod proto;

use std::env;

use proto::echo::{echo_service_client::EchoServiceClient, Text};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let mut client = EchoServiceClient::connect("http://[::1]:8080").await?;
    for content in env::args().skip(1) {
        let request = tonic::Request::new(Text { content });
        let response = client.echo_text(request).await?;
        println!("{}", response.get_ref().content);
    }
    Ok(())
}