使用grpc建立跨语言通讯
以下是使用gRPC从编译到生成SDK接口代码,并在C++和Python中使用的完整步骤:
1. 安装gRPC和依赖
C++环境
# 安装构建工具和依赖
sudo apt-get install build-essential autoconf libtool pkg-config cmake# 克隆gRPC仓库
git clone --recurse-submodules -b v1.62.0 https://github.com/grpc/grpc
cd grpc
mkdir -p cmake/build
cd cmake/build# 编译并安装gRPC
cmake -DgRPC_INSTALL=ON \-DgRPC_BUILD_TESTS=OFF \-DCMAKE_INSTALL_PREFIX=/usr/local \../..
make -j4
sudo make install
Python环境
# 安装Python的gRPC库
pip install grpcio grpcio-tools
2. 编写.proto文件
创建一个文件 example.proto
:
syntax = "proto3";package example;service Greeter {rpc SayHello (HelloRequest) returns (HelloReply) {}
}message HelloRequest {string name = 1;
}message HelloReply {string message = 1;
}
3. 生成接口代码
C++代码生成
# 生成代码(需安装protobuf和grpc_cpp_plugin)
protoc --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` example.proto
生成文件:example.pb.{h,cc}
和 example.grpc.pb.{h,cc}
。
Python代码生成
# 生成Python代码
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. example.proto
生成文件:example_pb2.py
和 example_pb2_grpc.py
。
4. 实现服务端和客户端
C++服务端 (server.cpp)
#include <grpcpp/grpcpp.h>
#include "example.grpc.pb.h"class GreeterServiceImpl final : public example::Greeter::Service {grpc::Status SayHello(grpc::ServerContext* context, const example::HelloRequest* request, example::HelloReply* reply) override {reply->set_message("Hello " + request->name());return grpc::Status::OK;}
};int main() {grpc::ServerBuilder builder;builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials());GreeterServiceImpl service;builder.RegisterService(&service);std::unique_ptr<grpc::Server> server(builder.BuildAndStart());server->Wait();return 0;
}
C++客户端 (client.cpp)
#include <grpcpp/grpcpp.h>
#include "example.grpc.pb.h"int main() {auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());std::unique_ptr<example::Greeter::Stub> stub = example::Greeter::NewStub(channel);example::HelloRequest request;request.set_name("World");example::HelloReply reply;grpc::ClientContext context;grpc::Status status = stub->SayHello(&context, request, &reply);if (status.ok()) {std::cout << "Response: " << reply.message() << std::endl;}return 0;
}
Python服务端 (server.py)
from concurrent import futures
import grpc
import example_pb2
import example_pb2_grpcclass Greeter(example_pb2_grpc.GreeterServicer):def SayHello(self, request, context):return example_pb2.HelloReply(message=f'Hello {request.name}')server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
example_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
Python客户端 (client.py)
import grpc
import example_pb2
import example_pb2_grpcchannel = grpc.insecure_channel('localhost:50051')
stub = example_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(example_pb2.HelloRequest(name='World'))
print(f"Response: {response.message}")
5. 编译和运行
C++项目编译
使用CMake(CMakeLists.txt
):
cmake_minimum_required(VERSION 3.10)
project(grpc_example)set(CMAKE_CXX_STANDARD 17)find_package(Protobuf REQUIRED)
find_package(gRPC REQUIRED)add_executable(server server.cpp example.pb.cc example.grpc.pb.cc)
target_link_libraries(server PRIVATE protobuf::libprotobuf grpc++)add_executable(client client.cpp example.pb.cc example.grpc.pb.cc)
target_link_libraries(client PRIVATE protobuf::libprotobuf grpc++)
编译命令:
mkdir build
cd build
cmake ..
make
运行:
# 启动服务端
./server# 运行客户端
./client
Python项目运行
直接运行脚本:
# 服务端
python server.py# 客户端
python client.py
常见问题
-
protoc版本不匹配
确保使用的protoc
版本与grpc-tools
版本一致。 -
C++链接错误
检查CMake中是否正确链接grpc++
和protobuf
。 -
Python模块导入错误
确保生成的example_pb2_grpc.py
和example_pb2.py
在Python路径中。
通过以上步骤,你可以在C++和Python中实现完整的gRPC通信。