0Pricing
Learn Rust Coding · レッスン

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Protobufとサービス定義
  2. tonic-buildでコードを生成する
  3. gRPCサーバーを実装する
  4. gRPCクライアントから呼び出す
← Learn Rust Codingに戻る