如何用 Rust 實現 gRPC 服務
在本文中,將展示如何使用 Rust 和 Proto 協議創建一個簡單的 gRPC 服務。
首先,我們運行以下命令來創建一個新的 Rust 應用程序:
cargo new rustgrpc
然後,在 Cargo.toml 文件中加入依賴項:
[dependencies]
tonic = "0.11"
tokio = { version = "1", features = ["full"] }
prost = "0.12.4"
[build-dependencies]
tonic-build = "0.11"
這個例子使用了 Tonic 庫,它是 gRPC 的一個 rust 實現。它是一個快速、高性能、開源、通用的 RPC 框架,使用 HTTP/2 協議,支持移動端!我們已經定義了依賴項,現在可以繼續編寫應用程序了。
創建 Proto 文件
我們將創建 Proto 文件來處理請求消息和響應消息。Proto 文件幫助客戶端和服務器理解發送和接收的消息。
在項目根目錄下創建一個名爲 “protos” 的新目錄,並創建一個名爲 “hello.proto” 的新文件。在文件中寫入以下內容:
syntax = "proto3";
package hello;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
語法聲明瞭我們想要使用的 proto 版本,在本例中是最新版本 proto3。package 聲明命名空間,在本例中爲 hello。接下來,我們定義接受 HelloRequest(name) 並返回 HelloReply (message) 的服務,爲了簡單起見,每個服務只聲明一個變量。
既然已經定義了 Proto 文件,接下來我們需要創建一個構建文件。在項目根目錄中創建一個名爲 “build.rs” 的新文件,並用以下內容填充它:
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("protos/hello.proto")?;
Ok(())
}
編寫代碼
在 src/main.rs 文件中,寫入以下代碼:
use tonic::{transport::Server, Request, Response, Status};
pub mod hello {
tonic::include_proto!("hello");
}
use hello::{greeter_server::{Greeter, GreeterServer}, HelloReply, HelloRequest};
我們需要定義一個結構體來實現我們的服務,在上面的代碼下面添加以下代碼:
#[derive(Default)]
pub struct MyGreeter {}
接下來,我們需要創建一個實現來處理 hello 請求和響應:
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(
&self,
request: Request<HelloRequest>,
) -> Result<Response<HelloReply>, Status> {
let reply = hello::HelloReply {
message: format!("Hello {}!", request.into_inner().name),
};
Ok(Response::new(reply))
}
}
這個函數接受一個 HelloRequest 並返回一個 HelloReply,最後,我們在 main 函數中啓動服務器並監聽請求:
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
let greeter = MyGreeter::default();
Server::builder()
.add_service(GreeterServer::new(greeter))
.serve(addr)
.await?;
Ok(())
}
編寫客戶端程序
在 src/bin / 目錄下,創建 client.rs 文件,在其中寫入以下代碼:
pub mod hello {
tonic::include_proto!("hello");
}
use hello::{greeter_client::GreeterClient, HelloRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = GreeterClient::connect("http://[::1]:50051").await?;
let request = tonic::Request::new(HelloRequest {
name: "Tonic".into(),
});
let response = client.say_hello(request).await?;
println!("RESPONSE={:?}", response);
Ok(())
}
運行應用程序
最後,我們需要做的就是構建和運行項目。
執行以下命令運行 server 端:
cargo run --bin rustgrpc
執行以下命令運行 client 端:
cargo run --bin client
如果一切正常,應該在 client 的終端中看到以下內容:
RESPONSE=Response { metadata: MetadataMap { headers: {"content-type": "application/grpc", "date": "", "grpc-status": "0"} }, message: HelloReply { message: "Hello Tonic!" }, extensions: Extensions }
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/k01C6K5ZV2WgPHzPN1yUmg