gRPC基本概念
gRPC
是什么?
gRPC是一种高性能、开源的远程过程调用(RPC)框架,由Google开发并开源。gRPC使用Google开发的Protocol Buffers(ProtoBuf)作为其默认的数据序列化和接口定义语言。
- 那
RPC
又是什么?
RPC是一种编程模型,它使得像本地方法调用一样调用远程计算机上的方法。通过RPC可以将不同的服务或不同的应用程序连接起来,使它们能够相互通信和交换数据,就像它们在同一台机器上运行一样。
安装gRPC
见https://blog.csdn.net/you_fathe/article/details/128192504
其中包含CMake、gcc/g++、gRPC、protobuf。
定义和实现 gRPC 服务
首先,定义一个.proto文件(例如,greeter.proto
),用于定义服务和消息格式
cpp
syntax = "proto3";
package example;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
使用protoc
编译器,根据.proto文件生成C++代码
cpp
protoc -I ./ --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` greeter.proto
服务端
cpp
#include <iostream>
#include <memory>
#include <grpcpp/grpcpp.h>
#include "greeter.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using example::Greeter;
using example::HelloRequest;
using example::HelloReply;
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string name = request->name();
std::string message = "Hello, " + name + "!";
reply->set_message(message);
return Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
}
int main() {
RunServer();
return 0;
}
客户端
cpp
#include <iostream>
#include <memory>
#include <grpcpp/grpcpp.h>
#include "greeter.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using example::Greeter;
using example::HelloRequest;
using example::HelloReply;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
std::string SayHello(const std::string& name) {
HelloRequest request;
request.set_name(name);
HelloReply reply;
ClientContext context;
Status status = stub_->SayHello(&context, request, &reply);
if (status.ok()) {
return reply.message();
} else {
return "RPC failed.";
}
}
private:
std::unique_ptr<Greeter::Stub> stub_;
};
int main() {
std::string server_address("localhost:50051");
GreeterClient greeter(grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials()));
std::string user("Alice");
std::string reply = greeter.SayHello(user);
std::cout << "Server replied: " << reply << std::endl;
return 0;
}
分别编译
cpp
g++ -std=c++11 -o server greeter.pb.cc greeter.grpc.pb.cc server.cpp `pkg-config --cflags --libs protobuf grpc++ grpc`
g++ -std=c++11 -o client greeter.pb.cc greeter.grpc.pb.cc client.cpp `pkg-config --cflags --libs protobuf grpc++ grpc`
报错
cpp
Perhaps you should add the directory containing `openssl.pc'
to the PKG_CONFIG_PATH environment variable
Package 'openssl', required by 'grpc', not found
解决
cpp
sudo apt install libssl-dev
export PKG_CONFIG_PATH=/usr/lib/pkgconfig:$PKG_CONFIG_PATH
再进行编译,并分别运行服务端和客户端
cpp
./server
./client
成功啦
cpp
root@sjn:/home# ./server
Server listening on 0.0.0.0:50051
root@sjn:/home# ./client
Server replied: Hello, Alice!