gRPC的C++编译及简单使用

8 篇文章 3 订阅
1 篇文章 0 订阅

grpc的编译及简单使用

1.grpc相关参考文档

2.使用cmake编译安装gRPC

  本文下载grpc是使用大陆外服务器下载grpc项目源码v1.32.X分支及其子模块submodule,总共1G左右,下载用时5分钟左右;大陆内用户可能首先需要解决下载问题。该章节主要翻译自gRPC C++快速开始–HelloWorld示例

2.1. 前置条件

  • 确保安装CMake且版本最好大于3.13

    检查cmake版本

    $ cmake --version
    

      在Linux下, 现有系统级别的cmake版本太低,可以通过一下脚本在本地目录安装更新的cmake版本。源码安装cmake等详细信息可参看文章CMake升级安装版本到3.17以上

    $ wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.17.0/cmake-3.17.0-Linux-x86_64.sh
    $ sh cmake-linux.sh -- --skip-license --prefix=/usr
    $ rm cmake-linux.sh
    
  • Linux编译工具

    $ sudo yum install -y build-essential autoconf libtool pkg-config
    
  • 配置环境变量(可选操作)

    选择一个目录作为本地安装路径,这里认为环境变量 MY_INSTALL_DIR 作为目录路径;

    # 构建路径
    $ export MY_INSTALL_DIR=/usr/local/
    # 确保目录已存在
    $ mkdir -p $MY_INSTALL_DIR
    # 将本地bin目录增加到path环境变量中
    $ export PATH="$PATH:$MY_INSTALL_DIR/bin"
    

2.2. Linux/Unix下使用

  在git克隆grpc项目后,在该目录下运行–recursive或update子模块submodules命令;如果想要编译动态库.so文件,运行cmake时添加-DBUILD_SHARED_LIBS=ON.

$ mkdir -p cmake/build
$ cd cmake/build
$ cmake -DgRPC_INSTALL=ON \
      -DgRPC_BUILD_TESTS=OFF \
      -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \
      ../..
# cmake ../.. -DCMAKE_INSTALL_PREFIX=/usr
$ make
$ make install

2.3. 依赖库管理

  对于解决依赖项,gRPC的CMAKE构建系统有两个选择。CMake可以为你编译构建依赖库,或者寻找已安装到操作系统的库文件并使用他们构建gRPC。执行方式通过CMake中 gRPC__PROVIDER 等参数的控制,例如gRPC_CARES_PROVIDER。这些选项如下执行:

  • module - 一起编译第三方依赖库和gRPC。这些依赖库源码是通过gRPC的git子模块获取到的。
  • package - 使用系统中已存在的依赖库,并将外部依赖库拷贝进行编译。这些可能来自当前编译系统的包管理器,也可以使用CMake的CMAKE_INSTALL_PREFIX选项提前安装并指定他们。

  例如,你可以设置gRPC_CARES_PROVIDER=module, 这样CMake将在构建gRPC之前构建c-ares。另一方面,如果设置gRPC_CARES_PROVIDER=package, CMake将会寻找已经安装到系统的c-ares并复制它来构建gRPC。

2.4. 构建够安装gRPC

如下步骤通过CMake安装gRPC:

  • 设置-DgRPC_INSTALL=ON
  • 构建安装路径,通过CMAKE_INSTALL_PREFIX变量指定。

  如果CMake是v3.13或更高,需要通过"module"模式来构建gRPC的第三方依赖库并且一键安装。而如果构建小于1.27版本的gRPC或使用小于3.13的CMake,需要选择"package"而不是"module"模式来构建第三方依赖。这就需要你确保当前系统的第三方依赖库可用。如下示例表示在安装gRPC之前,如何通过CMake安装依赖库。

# 所有gRPC的第三方依赖库需要已安装成功
$ cmake ../.. -DgRPC_INSTALL=ON                \
              -DCMAKE_BUILD_TYPE=Release       \
              -DgRPC_ABSL_PROVIDER=package     \
              -DgRPC_CARES_PROVIDER=package    \
              -DgRPC_PROTOBUF_PROVIDER=package \
              -DgRPC_RE2_PROVIDER=package      \
              -DgRPC_SSL_PROVIDER=package      \
              -DgRPC_ZLIB_PROVIDER=package
$ make
$ make install

交叉编译示例

2.5. protoc注意事项

  默认情况gRPC使用protocol buffers,你需要使用protoc编译器生成根服务器和客户端节点代码;如果使用gRPC源码安装并遍历下载了子模块,Makefile将查看是否已安装protoc并自动编译第三方protoc。

3.grpc的C++库使用

3.1. gRPC例子HelloWorld

  1. 编译范例HelloWorld

    • 从安装目录中运行示例/cpp/helloworld/cmake/build
    # 进入grpc项目中
    cd examples/cpp/helloworld
    # 准备构建,这里一定确保cmake版本正确
    $ mkdir -p cmake/build
    $ pushd cmake/build
    $ cmake ../..
    $ make -j
    
  2. 运行服务端

$ ./greeter_server
  1. 不同的终端运行客户端程序,显示如下说明已运行成功
$ ./greeter_client
Greeter received: Hello world
//14: failed to connect to all addresses
// Greeter received: RPC failed
//如果出现该问题,说明没有连接成功;查看是否服务端开启,且端口号和客户端一致;查看是否依赖项问题;

  1. 升级gRPC服务

  现在看下服务端如何用外部的一些方法更新应用,同时可用于客户端; gRPC服务里用使用了protocol buffers,我们可以找到很多文章解释如何在.proto文件定义服务;现在你需要知道的是,服务端和客户端都需要SayHello()的RPC函数方式,客户端通过它传递HelloRequest类型参数到服务端,服务端返回HelloResponse类型参数。通过examples/protos/helloworld.proto路径查看如下定义:

// 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;
}

  然后添加方法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;
}
  1. 重新生成代码

   在使用新服务方法前,需要重新编译更新下proto文件。然后从目录examples/cpp/helloworld/cmake/build下运行

$ make -j

  这样重新生成了helloworld.pb.{h,cc}和helloworld.grpc.pb.{h,cc}, 其中包含了服务端和客户端类文件, 以及类的传递、序列化、以及获取的请求和响应类型。 实际是执行编译helloworld.proto文件为cpp等文件,类似protoc --cpp_out=. helloworld.proto,并引用其编译为二进制文件;创建cpp的grpc文件,采用命令protoc --grpc_out . --cpp_out . -I . --plugin=protoc-gen-grpc=/usr/local/bin/grpc_cpp_plugin abc.proto;

  1. 升级并运行程序

  尽管上一步新生成了新代码,但仍需要在example应用中人工修改代码,执行调用新方法;

  • 服务端
  从example根目录下打开cpp/helloworld/greeter_server.cc,执行如下方法:
```protobuf
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;
	}
};
```

- 客户端

  现在protobuf根库中新的SayHelloAgain()已经可用。我们需要在GreeterClient中按照相同方式,完成SayHello()和SayHelloAgain()函数,文件greeter_client.cc中:

```protobuf
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”;
}
}
```

- 最终在主函数中运行新方法:
```bash
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;
}
```
  1. 运行执行

  在examples/cpp/helloworld/cmake/build目录中执行如下命令:

$ make -j
# 运行服务端程序
$ ./greeter_server
# 在不同终端运行如下客户端程序
$ ./greeter_client
# 看到如下输出
Greeter received: Hello world
Greeter received: Hello again world

  如果想要异步客户端和服务端,可以在源码目录中看到greeter_async_server,greeter_async_client等代码文件。

3.2. 例子RouteGuide

  读者可以参看gRPC中文手册中C++教程进行操作。这里不进一步展开。该程序主要是路线指引,借助json文件进行计算;

引用和提供了关于使用g++编译编译gRPC的示例命令行。这些命令用于编译客户端和服务器端的源文件,并链接所需的库文件以及使用Protobuf和gRPC的相关选项。这些命令还包含了一些编译标志,用于指定编译选项和库文件的位置。 引用展示了一个生成的C代码的片段,其中包含了一个IMLoginReq类。这个类定义了一些成员变量和成员函数,用于处理登录请求的消息。 总结起来,使用gRPC的C语言实现需要进行以下步骤: 1. 使用g++编译编译客户端和服务器端的源文件,使用适当的编译选项和库文件。 2. 使用Protobuf和gRPC生成相关的代码文件,例如.h和.cc文件。 3. 在代码中定义相应的类和函数来处理gRPC消息。 4. 编写客户端和服务器端的逻辑代码,实现相应的功能和交互。 5. 使用适当的命令行选项和库文件链接生成的可执行文件。 请注意,这只是一个概述,具体的实现步骤可能会因项目的具体需求和设置而有所不同。具体的实现细节和步骤应根据项目的要求和文档进行调整。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [gRPC应用C++](https://blog.csdn.net/weixin_40006133/article/details/111780229)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [C++使用gRPC实例](https://blog.csdn.net/qq_42120843/article/details/128147013)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值