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

2023-11-20

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文件进行计算;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gRPC的C++编译及简单使用 的相关文章

  • PM2 - 语法错误:严格模式之外尚不支持块范围声明

    我目前正在 Ubuntu 服务器上安装 NodeJS 服务 该应用程序是用 CoffeeScript 编写的 并且可以自行运行良好 这就是我设置项目的方式 cd test project nvm use v4 9 1 npm install
  • 如何在 CAS 服务管理中注册我的 Web 应用程序?

    我的学校想要实现一个CAS服务 我做了大部分配置 但是我需要注册webapp 如何在CAS服务管理中注册webapp 或者如果您有一些可以帮助我的样本 我将非常感激 我尝试过使用 cas 管理应用程序 版本为 4 2 x 我不确定您想使用什
  • 如何向服务器发送数据

    我想做一个登录 那么如何将用户名和密码发送到我的服务器呢 我为服务器编写了一个 php 脚本 他将收到用户名和密码 如果用户名和密码正确 他将响应 成功 那么如何发送到服务器呢 用 onResponse 发送后呢 您可以使用 OkHttp
  • Meteor 服务器 Websocket

    我正在寻找在 Meteor 服务器 而不是客户端 上创建一个 websocket 以连接到外部网站 我知道我要访问的 URL 以及期望的数据 但我不清楚如何准确地创建 websocket 本身 我所做的所有搜索都为我提供了客户端解决方案 但
  • Node 如何保持服务器进程处于活动状态?

    当 Node 的事件循环完全耗尽时 该进程就存在 然而 这不会发生在 HTTP 服务器上 例如 因为server listen 但这个函数到底有什么作用呢 看着the code https github com nodejs node bl
  • ipython 服务器无法启动:没有名为 notebook.notebookapp 的模块

    我一直在尝试按照几个教程设置 ipython 服务器 因为没有一个完全符合我的情况 几天前 我确实设法将其启动 但随后无法通过 url 访问它 今天它不再启动了 我找不到太多关于我得到的这个特定错误的信息 Traceback most re
  • Heroku 给出 500 错误,信息很少 + 内部服务器错误

    Heroku 在页面上显示此消息 internal server error 此错误显示在控制台中 GET 500内部服务器错误 检查 Heroku 应用程序的日志以查看更多详细信息 您可以使用流式传输日志Heroku CLI https
  • 如何使用 Express 和 NGINX 设置路由?

    我正在尝试使用 NGINX 作为反向代理来配置 Express 服务器 NGINX 提供静态文件 Express 提供动态内容 问题 正常的根链接有效 website com 但是当我导航到 website com api 时 我从 NGI
  • 如何在 Ubuntu Web 服务器上为 Dart 安装 pub(命令行使用)

    我已按照说明进行操作 在 Linux 选项卡下 将 Dart 安装到 Ubuntu Web 服务器上 Dart 本身工作正常 但我无法使用 Pub 命令 仅限 Dart 命令 如何为服务器安装 Pub 以下是使用 Aptitude apt
  • 套接字编程中的客户端到客户端消息传递

    我正在开发一个项目 该项目是基于 C 中的 WinSock 的服务器客户端应用程序 我已经完成了服务器和客户端之间通信所需的任何操作 我能够在它们之间发送和接收消息 现在我需要知道如何完成客户端到客户端消息传递部分以及必须如何完成工作 我只
  • 当我使用 XAMPP 服务器时 MySQL 将无法运行

    这是我在 XAMPP 上运行 MySQL 时的错误日志 我不知道如何修复它 它总是卡在尝试启动 MySQL 服务上 我尝试更改端口 但结果仍然相同 也尝试过重新安装但是问题还是一样 提前谢谢你 我得到的错误如下 2015 11 10 15
  • 服务器上 GetThumbnailImage 中的 C# 内存不足异常

    当用户向我们发送图像时 我正在运行以下代码来创建缩略图 public int AddThumbnail byte originalImage File parentFile File tnFile null try System Drawi
  • 如何在 Laravel 中为 20 分钟后的每条新记录制定调度程序任务?

    我有一个停车系统 我使用 Angular 6 Laravel 作为后端 但我有一个具体问题 我不知道正确的方法 公园有两个图腾 它们向我的服务器发送一个条目 只有当客户从出口走出图腾并进入付款区时 我才会检查客户是否无效 这是我的代码 当他
  • Paramiko 服务器:向客户端发出 stdout 已关闭的信号

    尝试在中实现测试服务器paramiko 无需修改客户端进行测试 我偶然发现了如何关闭的问题stdout流 使 stdout read 不会永远挂起 而不会在客户端的级别太低 到目前为止 我已经能够通过以下方式传达已完成的命令 简单文本输出到
  • Tomcat 和 TomEE、TomEE 和 TomEE Plus 之间有什么区别

    我想在服务器中部署 EJB Ear 但我对选择服务器感到非常困惑tomcat TomEE and TomEE Plus 两者有什么区别Tomcat and TomEE 其中有哪些新功能TomEE and TomEE Plus 在什么情况下才
  • 无法远程连接到Python Socket

    我已经使用 python 套接字和 Tkinter 创建了一个聊天应用程序 它在本地运行得很好 但是客户端无法远程连接到服务器 当我输入我的公共 IP 地址作为主机时 我已经完全端口转发了我的网络并且我知道如何很好地进行端口转发 当我运行在
  • 在云服务器中运行 python 脚本的最简单方法是什么?

    我有一个网络爬行 python 脚本 需要几个小时才能完成 并且无法在我的本地计算机上完整运行 有没有一种方便的方法可以将其部署到简单的 Web 服务器 该脚本基本上将网页下载到文本文件中 如何最好地实现这一点 谢谢 既然你说性能是一个问题
  • jinja2.exceptions.TemplateNotFound:index.html

    我尝试使用 Flask 打开 index html run py from app import app app run debug True init py from flask import Flask app Flask name f
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • 让 WSO2 IOT 服务器作为 Windows 服务运行

    我在Server 2012R2上安装了WSO2 IOT Server 我安装了 YAJSW 包装器并按照 WSO2 说明进行配置 当我启动 runConsole bat 来配置 Windows 服务时 出现以下错误 我设置了 JAVA HO

随机推荐

  • 【视频流上传播放功能】前后端分离用springboot-vue简单实现视频流上传和播放功能【详细注释版本,包含前后端代码】

    前言 我是前端程序猿一枚 不是后端的 如有写的有不规范的地方别介意哈 自己摸索了两天算是把这个功能做出来了 网上看了很多帖子没注释说实话 我看的基本是懵逼的 毕竟没有系统学过 所以现在做出来了就总结一下 自己多写点注释解释一下逻辑 让前端的
  • SpringBoot+MyBatisPlus+Thymeleaf+AdminLTE增删改查实战

    说明 AdminLTE是网络上比较流行的一款Bootstrap模板 包含丰富的样式 组件和插件 非常适用于后端开发人员做后台管理系统 因为最近又做了个后台管理系统 这次就选的是AdminLTE做主题模板发现效果不错 这里我把最核心的Spri
  • 华为机考练习python

    HJ108 求最小公倍数 while True try a b map int input split for i in range 1 b 1 if a i b 0 print a i break except break HJ107 求
  • linux中256错误,YUM安装遭遇: [Errno 256] No more mirrors to try

    把YUM配置好后 使用yum命令进行安装时 出现了如下错误 Downloading Packages ftp 192 168 220 46 RHEL6 2 x64 Server libaio devel 0 3 107 10 el6 x86
  • Calling a v8 javascript function from c++ with an argument

    Calling a v8 javascript function from c with an argument up vote 18 down vote favorite 8 I am working with c and v8 and
  • 笔试面试常考数据结构-单链表常用操作编程实现

    单链表是笔试以及面试手写代码中常考的数据结构之一 下面实现了单链表的常见操作 创建单链表 删除节点 打印单链表 包括正向打印以及逆向打印 反转单链表 找出单链表的倒数第K个节点 合并两个有序单链表等操作 代码 C cpp view plai
  • 【数据治理模型】哪种模型最适合您的组织?

    内部数据治理 第 2 部分 数据治理模型 在本系列的第一部分中 我们定义了数据治理并研究了导致大规模清理项目的失误 在这篇文章中 我们将研究常见的数据治理模型 哪些模型最适合不同类型的组织 没有单一的数据治理模型适合所有组织 在当今的业务中
  • RedisTemplate连接不释放导致服务异常

    最近在给一个项目做压测 刚开始时很正常 过一会服务就无法正常访问了 停止了压测任务再调用接口也同样没有响应 经排查是redis连接池没有释放导致的 解决方法 方法一 全局关闭事务 找到redis配置 将 enableTransactionS
  • jxl分割excel文件

    最近在实施一个项目 其中一项工作是处理历史数据 客户提供过来的数据是excel表格 超过20万条记录 由于目标系统导入限制 每次只能导入大小不超过8M的文件 所以需要对这些数据进行分割处理 在手工处理一遍后 觉得可以通过写一个程序来自动实现
  • 服务器 声音文件 nginx,docker nginx搭建视频音频服务器

    1 docker pull nginx 2 创建 nginx conf user nobody worker processes 1 error log logs error log error log logs error log not
  • python统计三国高频词,画条形图,绘词云图

    文章目录 前言 思路 代码 效果 总结 前言 记录一次期末作业 要求 1 统计三国演义 下卷 前十的高频词 含出现次数 2 根据上题结果 绘制高频词出现次数的条形图 3 生成三国演义 下卷 词云图 思路 1 open打开读取整篇文档 2 使
  • Vetur can‘t find `package.json`

    Vetur can t find package json 重新装了一下vscode 重新装vetur插件的时候右下角老是弹出提示 并且vetur的格式化也用不了了 我的解决办法是重新安装了vetur的版本 扩展里面找到vetur插件 点击
  • powershell报错:“irm : 请求被中止: 未能创建 SSL/TLS 安全通道“

    问题描述 powershell 执行下载的时候 报错 irm 请求被中止 未能创建 SSL TLS 安全通道 此时系统 所有的网络下载 经过https安全加密方式的TLS请求都会报错 因为加密版本不匹配的问题 可以通过以下命令 查看当前加密
  • TypeScript Property ‘XXX‘ does not exist on type ‘never‘.

    开发过程中出现这个错误是因为Typescript在执行代码检查时在该对象没有定义相应属性 这个错误不致命 遇到该错误有以下几种解决办法 1 将对象设置成 any this targetArray this options find item
  • 面向对象之反射

    目录 反射 优点 实战案例 案例 使用内置函数改造 反射内建函数注意事项 实例方法绑定和非绑定的区别 动态增加属性方法的区别 反射 其实它的核心本质其实就是利用字符串的形式去对象 模块 中操作 查找 获取 删除 添加 成员 一种基于字符串的
  • 【Android -- 开源库】表格 SmartTable 的基本使用

    介绍 1 功能 快速配置自动生成表格 自动计算表格宽高 表格列标题组合 表格固定左序列 顶部序列 第一行 列标题 统计行 自动统计 排序 自定义统计规则 表格图文 序列号 列标题格式化 表格各组成背景 文字 网格 padding等配置 表格
  • C++中的RTTI

    文章目录 dynamic cast运算符 指针类型的dynamic cast 引用类型的dynamic cast typeid运算符 使用RTTI type info类 参考资料 RTTI Runtime Type Information
  • 计算机专业2021考研分数线,2021研究生国家分数线是多少

    2021年考研国家线公布 再看看外语国家线最高的是文学类a类地区53 b类地区50分 每年虽然英语线不高 但是很多学生还是折在英语上 可惜啊 2021考研国家线 国家线公布干什么 一 做出选择 考研本身就是一个选拔性的考试 有人考上 自然也
  • 《时代》评出100位AI领域最具影响力人物,黄仁勋、马斯克、萨姆·奥特曼在列...

    编辑 腾讯科技 郝博阳 郭晓静 翻译 金鹿 在过去的一个世纪里 时代 杂志的封面反映了塑造社会的力量 今年也是如此 生成式人工智能 Generative AI 无疑是今年最受关注的重塑社会的力量 我现在看到的创新水平比我一生中见过的要强几个
  • gRPC的C++编译及简单使用

    grpc的编译及简单使用 1 grpc相关参考文档 grpc 主页 https grpc io grpc 文档 https grpc io docs grpc 简介 https grpc io docs what is grpc intro