以下是使用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_grpc
class 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_grpc
channel = 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通信。