欢迎您访问新疆栾骏商贸有限公司,公司主营电子五金轴承产品批发业务!
全国咨询热线: 400-8878-609

新闻资讯

技术学院

C++如何使用gRPC实现RPC通信?(服务端与客户端示例)

作者:冰火之心2025-12-24 00:00:00
C++实现gRPC通信需四步:1.定义.proto接口;2.用protoc生成C++代码;3.继承Service类实现服务端;4.通过Stub编写客户端调用,注意编译时链接gRPC和Protobuf库。

用 C++ 实现 gRPC RPC 通信,核心是定义协议(.proto)、生成 C++ 代码、实现服务端逻辑、编写客户端调用。整个流程不复杂但需注意编译依赖和运行时链接。

1. 定义 .proto 接口文件

先写一个 helloworld.proto,声明服务和消息结构:

syntax = "proto3";

package helloworld;

// 请求和响应消息 message HelloRequest { string name = 1; }

message HelloReply { string message = 1; }

// 定义 RPC 方法 service Greeter { rpc SayHello(HelloRequest) returns (HelloReply) {} }

这个文件描述了“客户端传名字,服务端回欢迎语”的简单交互。

2. 生成 C++ 代码

protoc 和 gRPC 插件生成头文件与源文件:

  • 安装 protoc 和 grpc_cpp_plugin(通常随 gRPC 源码或包管理器安装)
  • 执行命令(假设 protoc 在 PATH 中):
protoc -I . --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` helloworld.proto

会生成 helloworld.pb.h/.cc(数据序列化)和 helloworld.grpc.pb.h/.cc(服务桩)。

3. 编写服务端(Server)

继承生成的 Greeter::Service 类,重写 SayHello 方法:

#include "helloworld.grpc.pb.h"
#include 
#include 
#include 

class GreeterServiceImpl final : public helloworld::Greeter::Service { public: grpc::Status SayHello(grpc::ServerContext context, const helloworld::HelloRequest request, helloworld::HelloReply* reply) override { std::string prefix("Hello "); reply->set_message(prefix + request->name()); return grpc::Status::OK; } };

int main() { std::string server_address("0.0.0.0:50051"); GreeterServiceImpl service;

grpc::ServerBuilder builder; builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); builder.RegisterService(&service);

std::unique_ptr server(builder.BuildAndStart()); std::cout << "Server listening on " << server_address << std::endl; server->Wait(); // 阻塞等待 }

关键点:使用 InsecureServerCredentials() 表示明文通信;若需 TLS,改用 SslServerCredentials 并提供证书。

4. 编写客户端(Client)

用生成的 stub 调用远程方法:

#include "helloworld.grpc.pb.h"
#include 
#include 
#include 

int main(int argc, char** argv) { std::string target_str = "localhost:50051"; GreeterClient client( grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials()));

std::string user("world"); std::string reply = client.SayHello(user); std::cout << "Got reply: " << reply << std::endl; return 0; }

// 辅助类封装 stub 调用 class GreeterClient { public: explicit GreeterClient(std::sharedptr channel) : stub(helloworld::Greeter::NewStub(channel)) {}

std::string SayHello(const std::string& user) { helloworld::HelloRequest request; request.set_name(user);

helloworld::HelloReply reply;
grpc::ClientContext context;

grpc::Status status = stub_->SayHello(&context, request, &reply);

if (status.ok()) {
  return reply.message();
} else {
  return "RPC failed: " + status.error_message();
}

}

private: std::uniqueptr<:greeter::stub> stub; };

注意:客户端也用 InsecureChannelCredentials() 对应服务端的不安全模式;异步调用可改用 AsyncStub

5. 编译与运行

需链接 gRPC 和 Protobuf 库(以 CMake 为例):

find_package(gRPC CONFIG REQUIRED)
find_package(Protobuf REQUIRED)

add_executable(server server.cpp helloworld.pb.cc helloworld.grpc.pb.cc) target_link_libraries(server PRIVATE grpc++ grpc++_reflection protobuf::libprotobuf)

add_executable(client client.cpp helloworld.pb.cc helloworld.grpc.pb.cc) target_link_libraries(client PRIVATE grpc++ protobuf::libprotobuf)

确保环境已安装 gRPC(推荐用 官方源码编译 或 vcpkg/conan 管理)。运行时先启动 server,再运行 client。