C++ grpc
1.C++ grpc
- server中定义函数,client通过stub远程访问server中定义的函数。
- 使用grpc可以实现跨语言调用
- gRPC使用特殊的protoc插件去使用proto文件生成代码C++代码【什么插件??答:就是安装目录下面的bin中的grpc_cpp_plugin,就是一个可执行文件而已嘛】
- protobuf官方教程
brpc与grpc的区别:
- brpc是单语言多协议的,即只能在C++语言中使用,但是远程调用时客户端和服务器之间的通信协议有很多种,如http、rtmp/flv/hls等。
- grpc是多语言单协议的,即可以使用一种编程语言编写函数,然后使用其他编程语言调用此远程函数。
参考:官方文档
1.0 C++开源库的安装和使用流程:
- 安装开源代码所需要的依赖
- 下载开源代码
- 设置安装路径和其他参数
- 编译。编译成功以后,一般会在安装路径下面看到三个主要的文件夹bin、lib、include。有了这三个文件就可以使用代码了
1.1 安装和入门(Quick start)
1.下载和安装
首先Quick start中介绍了grpc库的下载和安装,但是按照官方文档中使用git clone
下载grpc库会出现错误:Failed to recurse into submodule path
解决方法:进入grpc目录,执行git submodule update --init --recursive,运行这个命令直到不出现克隆错误,如果一直出现上面的那个错误,代码网络的问题,网络被qiang了。
2.在proto中添加方法
在proto中添加方法SayHelloAgain,并在server中实现SayHelloAgain方法,最后在client中使用server中实现的SayHelloAgain方法。
1.2 基础教程(Basics tutorial)
1.编译和运行examples/cpp/route_guide:
$ cd examples/cpp/route_guide
$ mkdir -p cmake/build
$ cd cmake/build
$ cmake -DCMAKE_PREFIX_PATH=$MY_INSTALL_DIR ../.. # $MY_INSTALL_DIR为安装的路径,比如我的是/home/ubuntu/softwares/grpc。
$ make route_guide.grpc.pb.o
$ make
# 运行
$ ./route_guide_server
$ ./route_guide_client # 开启另一终端:
上述命令中的make route_guide.grpc.pb.o
相当于:
$ protoc -I ../../protos --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ../../protos/route_guide.proto
$ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto
2.gRPC允许您定义四种服务方法
service中定义的参数和返回值都有可能是stream类型的,也有可能不是,这就将服务分成了四类。
stream类型就是一组相同类型的数据,如rpc ListFeatures(Rectangle) returns (stream Feature) {}
其中stream就是代表可能返回很多个Feature类型的数据,而rpc GetFeature(Point) returns (Feature) {}
只返回一个Feature类型的数据。
3.grpc_cpp_plugin插件按照proto文件生成对应的c++代码:
- route_guide.pb.h和route_guide.pb.cc中存放的是proto文件中的message对应的类
- route_guide.grpc.pb.h和route_guide.grpc.pb.cc中存放的是proto文件中的service对应的类
4.实现server
实现proto定义的service:
- 继承route_guide.grpc.pb.h中的类
RouteGuide::Service
并重写其中的函数,即class RouteGuideImpl final : public RouteGuide::Service
。RouteGuide为proto文件中定义的service。
如果继承的是RouteGuide::AsyncService
,则实现的是异步的接口。 - 所有方法的第一个参数都是
ServerContext* context
代表rpc上下文。
所有方法都可以被多个线程同时调用,所以我们需要在实现方法的时候需要保证线程安全。 - 使用
ServerWriter<T>* writer
发送T类型的stream数据
使用ClientReader<T>* reader
接收T类型的stream数据
使用ServerReaderWriter<T1, T2>* stream
发送T1类型的stream数据,接收T2类型的stream数据
启动gRPC server:
- 创建一个ServerBuilder对象builder,向builder添加端口和RouteGuideImpl对象
- 使用
builder.BuildAndStart()
初始化一个server server->Wait();
等待server被杀死
5.client使用server定义的接口
- 使用
grpc::CreateChannel
生成channel - 使用
stub_(RouteGuide::NewStub(channel)
初始化stub - 使用sub调用远程函数,调用的形式和本地调用没有什么不同。【注】本文的所有函数调用都是阻塞调用,即需要等到被调用的远程函数响应以后,才能继续执行下一步。
6.examples/cpp/route_guide/CMakeLists.txt
route_guide中的CMakeLists.txt文件中的include(../cmake/common.cmake),common.cmake中提到了两种使用grpc的手段:
- 使用已经下载好的grpc源码(GRPC_AS_SUBMODULE)
- 直接从github上获取grpc源码(GRPC_FETCHCONTENT)
CMakeLists.txt还没看完,待续。。。