gRPCクライアントから呼び出す
サービスを利用します。
「gRPCクライアントから呼び出す」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。
生成されたクライアント
各サービスについて、tonicはgreeter_clientモジュール内にクライアント構造体(例:GreeterClient)を生成します。rpcごとに1つのasyncメソッドが公開されます。
トランスポートチャネルから構築するか、エンドポイントに直接接続して構築します。
use greeter::v1::greeter_client::GreeterClient;
use greeter::v1::HelloRequest;サーバーに接続する
最も簡単な方法はGreeterClient::connectです。アドレス文字列を受け取り、接続済みのクライアントを返します。
asyncコンテキスト内で実行する必要があるため、#[tokio::main]の下で.awaitを付けて呼び出してください。
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = GreeterClient::connect("http://[::1]:50051").await?;
Ok(())
}Unary呼び出しを行う
メッセージをtonic::Requestでラップする(またはRequest::newを使う)ことで、生成されたメソッドを呼び出せます。
レスポンスはtonic::Responseです。.into_inner()を呼び出すとメッセージを読み取れます。
let request = tonic::Request::new(HelloRequest { name: "Ada".into() });
let response = client.say_hello(request).await?;
println!("{}", response.into_inner().message);Statusエラーを処理する
サーバーがエラーを返すと、呼び出しはErr(Status)として解決されます。status.code()とstatus.message()を調べて処理してください。
これはサーバー側と同じ仕組みです。NotFoundやUnauthenticatedなどのコードがクライアントに返されます。
match client.say_hello(req).await {
Ok(resp) => println!("{}", resp.into_inner().message),
Err(status) => eprintln!("{}: {}", status.code(), status.message()),
}チャネルを構築する
再利用や設定が必要な場合は、Endpointを使ってChannelを明示的に構築します。タイムアウト、TCP keepalive、接続オプションを設定できます。
その後、GreeterClient::new(channel)でクライアントを構築します。
use tonic::transport::{Channel, Endpoint};
let channel = Endpoint::from_static("http://[::1]:50051")
.timeout(std::time::Duration::from_secs(5))
.connect()
.await?;
let mut client = GreeterClient::new(channel);メタデータを送信する
送信前にリクエストのメタデータへ挿入することで、認証トークンなどのヘッダーを付加できます。
値にはMetadataValueを使います。有効なASCIIヘッダー値でなければなりません。
use tonic::metadata::MetadataValue;
let mut req = tonic::Request::new(HelloRequest { name: "Ada".into() });
let token: MetadataValue<_> = "Bearer abc123".parse()?;
req.metadata_mut().insert("authorization", token);呼び出しごとのデッドライン
サーバーの処理が遅い場合にクライアントがハングしないよう、デッドラインを設定します。リクエストのset_timeoutは、制限時間を超えるとDeadlineExceededステータスで処理を中止します。
デッドラインはサーバーにも伝播するため、サーバーは処理を早期に停止できます。
let mut req = tonic::Request::new(HelloRequest { name: "Ada".into() });
req.set_timeout(std::time::Duration::from_secs(2));
let resp = client.say_hello(req).await?;サーバーストリームを消費する
サーバーストリーミングの呼び出しはストリームを返します。into_inner()で取り出し、ループ内でmessage().awaitを使って、Noneが返るまでメッセージを取得します。
各反復で、デコード済みのレスポンスが1つ得られます。
let mut stream = client.server_stream(req).await?.into_inner();
while let Some(item) = stream.message().await? {
println!("{:?}", item);
}クライアントストリーミング
クライアントストリーミングの呼び出しでは、リクエストのasyncストリームを渡します。イテレーターやチャネルをtokio_streamでラップして、メソッドに渡してください。
送信を完了すると、1つのレスポンスが返されます。
use tokio_stream::iter;
let outbound = iter(vec![msg1, msg2, msg3]);
let response = client.client_stream(Request::new(outbound)).await?;
println!("{:?}", response.into_inner());TLS接続
暗号化されたトランスポートを使うには、CA証明書とサーバーのドメインを指定してClientTlsConfigを設定し、https経由で接続します。
tonic依存関係のtls機能が必要です。
use tonic::transport::{ClientTlsConfig, Endpoint};
let tls = ClientTlsConfig::new().domain_name("example.com");
let channel = Endpoint::from_static("https://example.com:50051")
.tls_config(tls)?
.connect()
.await?;クライアントを再利用する
基盤となるChannelは安価にcloneでき、1つのHTTP/2接続上で複数のリクエストを多重化します。再接続するのではなく、タスク間でクライアントをcloneしてください。
これにより、並行実行時の接続確立コストを低く抑えられます。
let client = GreeterClient::new(channel);
let mut c1 = client.clone();
let mut c2 = client.clone();
// use c1 and c2 in separate tokio tasksクイックチェック
tonicでUnaryクライアント呼び出しの結果を読み取るには、どうすればよいですか?
まとめ
生成されたクライアントに接続し、Unary呼び出しを行い、Statusエラーを処理し、設定済みのチャネルを構築し、メタデータを送信し、デッドラインを設定し、サーバーとクライアントのストリームを消費し、TLSを有効にし、安価にcloneできるクライアントを再利用しました。
これで、tonicを基盤とするgRPCサービスをエンドツーエンドで構築できるようになりました。
よくある質問
「gRPCクライアントから呼び出す」レッスンは無料ですか?
はい。「gRPCクライアントから呼び出す」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。
「gRPCクライアントから呼び出す」で何を学びますか?
サービスを利用します。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Learn Rust Codingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「gRPCクライアントから呼び出す」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLearn Rust Codingレッスンでコードを書いて実行できますか?
はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Protobufとサービス定義
- tonic-buildでコードを生成する
- gRPCサーバーを実装する
- gRPCクライアントから呼び出す