クイックスタート
このガイドでは、簡単な動作例を用いて、C++でgRPCを使い始める方法を説明します。
クイックスタート
C++の世界では、プロジェクトの依存関係を管理するための普遍的に受け入れられている標準はありません。このクイックスタートのHello Worldの例をビルドして実行する前に、gRPCをビルドしてインストールする必要があります。
gRPCとProtocol Buffersをビルドし、ローカルにインストールする
このセクションの手順では、cmake
を使用してgRPCとProtocol Buffersをビルドし、ローカルにインストールする方法を説明します。代わりにbazelを使用したい場合は、ソースからビルドを参照してください。
セットアップ
ローカルにインストールされたパッケージを保持するディレクトリを選択します。このページでは、環境変数MY_INSTALL_DIR
がこのディレクトリのパスを保持していることを前提としています。例えば
$ export MY_INSTALL_DIR=$HOME/.local
ディレクトリが存在することを確認してください
$ mkdir -p $MY_INSTALL_DIR
ローカルのbin
フォルダをパス変数に追加します。例えば
$ export PATH="$MY_INSTALL_DIR/bin:$PATH"
cmakeをインストールする
cmake
のバージョン3.13以降が必要です。次の手順に従ってインストールしてください
Linux
$ sudo apt install -y cmake
macOS
$ brew install cmake
cmake
の一般的なインストール手順については、CMakeのインストールを参照してください。
cmake
のバージョンを確認してください
$ cmake --version
cmake version 3.19.6
Linuxでは、システム全体のcmake
のバージョンが古すぎる場合があります。次の方法で、より新しいバージョンをローカルインストールディレクトリにインストールできます
$ wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.19.6/cmake-3.19.6-Linux-x86_64.sh
$ sh cmake-linux.sh -- --skip-license --prefix=$MY_INSTALL_DIR
$ rm cmake-linux.sh
その他の必要なツールをインストールする
gRPCをビルドするために必要な基本ツールをインストールします
Linux
$ sudo apt install -y build-essential autoconf libtool pkg-config
macOS
$ brew install autoconf automake libtool pkg-config
grpc
リポジトリをクローンする
grpc
リポジトリとそのサブモジュールをクローンします
$ git clone --recurse-submodules -b v1.62.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
gRPCとProtocol Buffersをビルドしてインストールする
必須ではありませんが、gRPCアプリケーションは通常、サービス定義とデータシリアライゼーションのためにProtocol Buffersを利用し、例のコードではproto3を使用します。
次のコマンドは、gRPCとProtocol Buffersをビルドしてローカルにインストールします
$ cd grpc
$ mkdir -p cmake/build
$ pushd cmake/build
$ cmake -DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \
../..
$ make -j 4
$ make install
$ popd
重要
gRPCをローカルにインストールすることを強くお勧めします。適切に設定されたCMAKE_INSTALL_PREFIX
を使用してください。これは、gRPCをグローバルにインストールした後でアンインストールする簡単な方法がないためです。詳細
- gRPC C++のビルドに関する完全な手順については、ソースからのビルドを参照してください。
- gRPCをC++プロジェクトの依存関係として追加する方法の一般的な手順については、gRPC C++の使用を開始するを参照してください。
例をビルドする
例のコードは、前のセクションの手順の一部としてクローンしたgrpc
リポジトリのソースの一部です。
例のディレクトリに移動します
$ cd examples/cpp/helloworld
cmake
を使用して例をビルドします$ mkdir -p cmake/build $ pushd cmake/build $ cmake -DCMAKE_PREFIX_PATH=$MY_INSTALL_DIR ../.. $ make -j 4
注意
ビルドが失敗する場合?ほとんどの問題は、この時点で、インストールに不備があることが原因です。cmake
の正しいバージョンがあり、インストールを注意深く再確認してください。
試してみよう!
例のビルドディレクトリexamples/cpp/helloworld/cmake/build
から例を実行します
サーバーを実行します
$ ./greeter_server
別のターミナルから、クライアントを実行してクライアントの出力を確認します
$ ./greeter_client Greeter received: Hello world
おめでとうございます!gRPCを使用してクライアント/サーバーアプリケーションを実行しました。
gRPCサービスを更新する
次に、クライアントが呼び出すための追加のメソッドをサーバーでアプリケーションを更新する方法を見てみましょう。gRPCサービスは、プロトコルバッファーを使用して定義されます。.proto
ファイルでサービスを定義する方法については、gRPCの概要と基本チュートリアルで詳しく知ることができます。今のところ知っておく必要があるのは、サーバーとクライアントスタブの両方に、クライアントからのHelloRequest
パラメータを受け取り、サーバーからのHelloReply
を返すSayHello()
RPCメソッドがあること、そしてこのメソッドがこのように定義されているということです
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
examples/protos/helloworld.protoを開き、同じリクエストタイプとレスポンスタイプを使用して、新しいSayHelloAgain()
メソッドを追加します
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
// Sends another greeting
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
ファイルを保存することを忘れないでください!
gRPCコードを再生成する
新しいサービスメソッドを使用する前に、更新されたprotoファイルを再コンパイルする必要があります。
例のビルドディレクトリexamples/cpp/helloworld/cmake/build
から、実行します
$ make -j 4
これにより、生成されたクライアントクラスとサーバークラス、およびリクエストタイプとレスポンスタイプを入力、シリアライズ、および取得するためのクラスを含むhelloworld.pb.{h,cc}
とhelloworld.grpc.pb.{h,cc}
が再生成されます。
アプリケーションを更新して実行する
新しい生成されたサーバーコードとクライアントコードがありますが、例のアプリケーションの人間が書いた部分で新しいメソッドを実装して呼び出す必要があります。
サーバーを更新する
例のルートディレクトリからgreeter_server.cc
を開きます。次のように新しいメソッドを実装します
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
// ...
}
Status SayHelloAgain(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello again ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};
クライアントを更新する
新しいSayHelloAgain()
メソッドがスタブで使用可能になりました。すでに存在するSayHello()
と同じパターンに従い、新しいSayHelloAgain()
メソッドをGreeterClient
に追加します
class GreeterClient {
public:
// ...
std::string SayHello(const std::string& user) {
// ...
}
std::string SayHelloAgain(const std::string& user) {
// Follows the same pattern as SayHello.
HelloRequest request;
request.set_name(user);
HelloReply reply;
ClientContext context;
// Here we can use the stub's newly available method we just added.
Status status = stub_->SayHelloAgain(&context, request, &reply);
if (status.ok()) {
return reply.message();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
}
最後に、main()
でこの新しいメソッドを呼び出します
int main(int argc, char** argv) {
// ...
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
reply = greeter.SayHelloAgain(user);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}
実行!
以前と同じようにクライアントとサーバーを実行します。例のビルドディレクトリexamples/cpp/helloworld/cmake/build
から次のコマンドを実行します
変更を加えた後、クライアントとサーバーをビルドします
$ make -j 4
サーバーを実行します
$ ./greeter_server
別のターミナルで、クライアントを実行します
$ ./greeter_client
次の出力が表示されます
Greeter received: Hello world Greeter received: Hello again world