使用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.pyexample_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

常见问题

  1. protoc版本不匹配
    确保使用的protoc版本与grpc-tools版本一致。

  2. C++链接错误
    检查CMake中是否正确链接grpc++protobuf

  3. Python模块导入错误
    确保生成的example_pb2_grpc.pyexample_pb2.py在Python路径中。


通过以上步骤,你可以在C++和Python中实现完整的gRPC通信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

telllong

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值