gRPC 基本使用
gRPC 是一个高性能、开源且通用的远程过程调用 (RPC) 框架,它能够让你从客户端轻松地调用另一台机器上的服务端方法,就像调用本地对象一样,同时为你管理了很多细节,如线程管理和网络传输等。gRPC 支持多种语言,并且默认使用 Protocol Buffers 作为接口定义语言(IDL)来定义服务接口以及消息格式。
下面是 gRPC 的基本使用步骤:
1、定义服务接口
首先使用 protobuf 语言定义服务接口,定义在以 .proto
结尾的文件中,其中包含了服务的名称、服务的方法以及每个方法的消息格式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| syntax = "proto3";
package example;
service Echo { rpc SayHello (HelloRequest) returns (HelloResponse); }
message HelloRequest { string greeting = 1; }
message HelloResponse { string reply = 1; }
|
2、生成代码
使用 Protocol Buffers 编译器 (protoc
) 和相应语言对应的 gRPC 插件生成客户端和服务器端的存根代码。
1 2 3 4
| // 生成 c++ 消息类: echo.pb.h echo.pb.cc protoc -I=. --cpp_out=. echo.proto // 生成 gRPC 存根代码: echo.grpc.pb.h ehco.grpc.pb.cc protoc -I=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` echo.proto
|
protoc 命令解析
-I
:指定 .proto
文件的搜索路径
--cpp_out
:指定生成 C++ 代码的输出路径
--grpc_out
:指定生成 gRPC 存根代码的输出路径
--plugin=proto-gen-grpc='which grpc_cpp_plugin'
:指定要使用的插件
3、实现服务
继承自动生成的服务类并实现其中的虚函数。
1 2 3 4 5 6 7 8 9
| class EchoServiceImpl final : public example::Echo::Service { public: grpc::Status SayHello(grpc::ServerContext* context, const example::HelloRequest* request, example::HelloResponse* reply) override { std::string prefix("Hello "); reply->set_reply(prefix + request->greeting()); return grpc::Status::OK; } };
|
4、创建服务器
创建一个 gRPC 服务实例,并将实现的服务注册到服务器上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <iostream> #include <memory>
#include <grpcpp/grpcpp.h> #include "example.pb.h" #include "example.grpc.pb.h"
int main(int argc, char** argv) { std::string server_address("0.0.0.0:50051");
EchoServiceImpl service;
grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
return 0; }
|
5、创建客户端
创建一个客户端实例连接到 gRPC 服务器,并调用服务的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <iostream> #include <memory>
#include <grpcpp/grpcpp.h> #include "example.pb.h" #include "example.grpc.pb.h"
int main() { std::shared_ptr<grpc::Channel> channel = grpc::CreateChannel( "localhost:50051", grpc::InsecureChannelCredentials());
std::unique_ptr<example::Echo::Stub> stub = example::Echo::NewStub(channel);
example::HelloRequest request; request.set_greeting("world");
example::HelloResponse reply;
grpc::ClientContext context;
grpc::Status status = stub->SayHello(&context, request, &reply);
if (status.ok()) { std::cout << "Greeter received: " << reply.reply() << std::endl; } else { std::cout << "Greeter RPC failed: " << status.error_code() << ": " << status.error_message() << std::endl; }
return 0; }
|