快速入门

本指南通过一个简单的可运行示例,带你开始使用 C++ 中的 gRPC。

快速入门

本指南通过一个简单的可运行示例,带你开始使用 C++ 中的 gRPC。

在 C++ 世界中,没有普遍接受的项目依赖管理标准。在构建并运行本快速入门的 Hello World 示例之前,你需要构建并安装 gRPC。

构建并本地安装 gRPC 和 Protocol Buffers

本节中的步骤解释了如何使用 cmake 构建并本地安装 gRPC 和 Protocol Buffers。如果你更喜欢使用 bazel,请参阅从源代码构建

设置

选择一个目录来存放本地安装的包。本页面假设环境变量 MY_INSTALL_DIR 存储此目录路径。例如

  • Linux / macOS
export MY_INSTALL_DIR=$HOME/.local

确保目录存在

mkdir -p $MY_INSTALL_DIR

将本地 bin 文件夹添加到你的路径变量,例如

export PATH="$MY_INSTALL_DIR/bin:$PATH"
  • Windows
set MY_INSTALL_DIR=%USERPROFILE%\cmake

确保目录存在

mkdir %MY_INSTALL_DIR%

将本地 bin 文件夹添加到你的路径变量,例如

set PATH=%PATH%;$MY_INSTALL_DIR\bin

安装 cmake

你需要 cmake 3.16 或更高版本。如果你没有安装,请按照以下说明进行安装

  • Linux

    sudo apt install -y cmake
    
  • macOS

    brew install cmake
    
  • Windows

    choco install cmake
    
  • 有关 cmake 的通用安装说明,请参阅安装 CMake

检查 cmake 版本

cmake --version
cmake version 3.30.3

在 Linux 下,系统范围内的 cmake 版本通常过旧。你可以将更新的版本安装到本地安装目录,如下所示

wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.30.3/cmake-3.30.3-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.74.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc

构建并安装 gRPC 和 Protocol Buffers

虽然不是强制性的,但 gRPC 应用程序通常利用 Protocol Buffers 进行服务定义和数据序列化,并且示例代码使用 proto3

以下命令构建并本地安装 gRPC 和 Protocol Buffers

  • Linux & macOS

    cd grpc
    mkdir -p cmake/build
    pushd cmake/build
    cmake -DgRPC_INSTALL=ON \
          -DgRPC_BUILD_TESTS=OFF \
          -DCMAKE_CXX_STANDARD=17 \
          -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \
          ../..
    make -j 4
    make install
    popd
    
  • Windows

    mkdir "cmake\build"
    pushd "cmake\build"
    cmake -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DCMAKE_CXX_STANDARD=17 -DCMAKE_INSTALL_PREFIX=%MY_INSTALL_DIR% ..\..
    cmake --build . --config Release --target install -j 4
    popd
    

更多信息

构建示例

示例代码是 grpc 仓库源代码的一部分,你在上一节的步骤中已经克隆了它。

  1. 切换到示例目录

    cd examples/cpp/helloworld
    
  2. 使用 cmake 构建示例

    • Linux & macOS

      mkdir -p cmake/build
      pushd cmake/build
      cmake -DCMAKE_PREFIX_PATH=$MY_INSTALL_DIR ../..
      make -j 4
      
    • Windows

      mkdir "cmake\build"
      pushd "cmake\build"
      cmake -DCMAKE_INSTALL_PREFIX=%MY_INSTALL_DIR% ..\..
      cmake --build . --config Release -j 4
      popd
      

试运行!

从示例的构建目录 examples/cpp/helloworld/cmake/build 运行示例

  1. 运行服务器

    ./greeter_server
    
  2. 在另一个终端中,运行客户端并查看客户端输出

    ./greeter_client
    Greeter received: Hello world
    

恭喜!您刚刚运行了一个使用 gRPC 的客户端-服务器应用程序。

更新 gRPC 服务

现在,我们来看看如何更新应用程序,在服务器上添加一个供客户端调用的额外方法。我们的 gRPC 服务是使用 protocol buffers 定义的;你可以在gRPC 简介基础教程中了解更多关于如何在 .proto 文件中定义服务的信息。目前,你需要知道的是,服务器和客户端存根都具有一个 SayHello() RPC 方法,该方法从客户端接收 HelloRequest 参数并从服务器返回 HelloReply,并且此方法的定义如下

// 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 运行

  • Linux & macOS
make -j 4
  • Windows
cmake --build . --config Release -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() 相同的模式,并向 GreeterClient 添加一个新的 SayHelloAgain() 方法

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 执行以下命令

  1. 更改后构建客户端和服务器

    • Linux & macOS
    make -j 4
    
    • Windows
    cmake --build . --config Release -j 4
    
  2. 运行服务器

    ./greeter_server
    
  3. 在另一个终端上,运行客户端

    ./greeter_client
    

    你将看到以下输出

    Greeter received: Hello world
    Greeter received: Hello again world
    

接下来

最后修改于 2025 年 4 月 19 日: Update quickstart.md (#1420) (fe6a359)