自定义gRPC服务端的C++客户端开发技术求助
通用gRPC C++客户端实现方案(适配你的inference.proto)
第一步:补全proto文件的服务定义
你的inference.proto仅定义了消息结构,缺少gRPC服务接口,需要先补充:
// The request message containing the images. repeated keyword for list message InferenceRequest { repeated int32 length = 1; repeated int32 width = 2; repeated int32 type = 3; repeated bytes image = 4; } message InferenceReply { repeated bytes pred = 1; } // 新增服务定义,对应你Python服务端的RPC方法名 service InferenceService { rpc Predict(InferenceRequest) returns (InferenceReply) {} }
第二步:编译proto生成C++代码
使用protoc工具结合gRPC C++插件生成代码,执行以下命令:
# 生成gRPC相关代码 protoc --grpc_out=. --plugin=protoc-gen-grpc=$(which grpc_cpp_plugin) inference.proto # 生成Protobuf消息代码 protoc --cpp_out=. inference.proto
执行后会生成4个文件:inference.pb.h、inference.pb.cc、inference.grpc.pb.h、inference.grpc.pb.cc,这些文件需要纳入你的C++项目。
第三步:编写C++客户端代码
以下是适配你的消息结构的客户端实现示例:
#include <iostream> #include <memory> #include <vector> #include <string> #include <grpcpp/grpcpp.h> #include "inference.grpc.pb.h" #include "inference.pb.h" // 替换为你proto文件中定义的命名空间(如果没有指定,默认是空命名空间,可省略) using namespace your_proto_namespace; class InferenceClient { public: explicit InferenceClient(std::shared_ptr<grpc::Channel> channel) : stub_(InferenceService::NewStub(channel)) {} std::vector<std::string> SendInferenceRequest( const std::vector<int>& lengths, const std::vector<int>& widths, const std::vector<int>& types, const std::vector<std::string>& images) { InferenceRequest request; // 填充请求参数 for (int l : lengths) request.add_length(l); for (int w : widths) request.add_width(w); for (int t : types) request.add_type(t); for (const auto& img : images) request.add_image(img); InferenceReply reply; grpc::ClientContext context; // 调用RPC方法 grpc::Status status = stub_->Predict(&context, request, &reply); std::vector<std::string> results; if (status.ok()) { for (int i = 0; i < reply.pred_size(); ++i) { results.emplace_back(reply.pred(i)); } } else { std::cerr << "RPC调用失败: " << status.error_message() << std::endl; } return results; } private: std::unique_ptr<InferenceService::Stub> stub_; }; int main() { // 连接到你的gRPC服务端,替换为实际的服务地址(如你的Docker容器端口映射后的地址) auto channel = grpc::CreateChannel( "localhost:50051", grpc::InsecureChannelCredentials()); InferenceClient client(channel); // 示例数据,替换为实际的图像参数和bytes数据 std::vector<int> lengths = {224}; std::vector<int> widths = {224}; std::vector<int> types = {1}; std::vector<std::string> images = {"your_image_raw_bytes_here"}; auto predictions = client.SendInferenceRequest(lengths, widths, types, images); for (const auto& pred : predictions) { std::cout << "预测结果: " << pred << std::endl; } return 0; }
第四步:编译C++客户端
使用g++编译客户端代码,链接gRPC和Protobuf库:
g++ -std=c++17 inference.pb.cc inference.grpc.pb.cc client.cpp -o inference_client \ `pkg-config --libs grpc++ grpc protobuf` -lgrpc++_reflection -ldl
注意:确保系统已安装gRPC和Protobuf的开发依赖(如Ubuntu下可通过
apt install libgrpc-dev libprotobuf-dev grpc-tools安装)。
关键注意事项
- 确保proto文件中的服务方法名(如
Predict)与你的Python服务端实现的RPC方法完全一致 - C++中用
std::string承载图像bytes数据,与Python的bytes类型天然兼容 - 如果服务端使用流式RPC,需调整客户端代码的调用逻辑(当前示例为一元RPC,与常规Python客户端逻辑匹配)
内容的提问来源于stack exchange,提问作者Yahya Nik
相关产品推荐
相关产品推荐

