gRPC是一个高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言,能够基于语言自动生成客户端和服务端功能库。
1.新建工程GrpcClient、GrpcServer和GrpcLibrary
添加 - 新建项目 - 控制台应用 GrpcClient、GrpcServer。
添加 - 新建项目 - 类库 GrpcLibrary。 工程中的三个项目情况如下:
2.自定义服务
在项目GrpcLibrary里添加HelloWorld.proto用以生成代码。
-
syntax =
"proto3";
-
package GrpcLibrary;
-
-
service GrpcService {
-
rpc
SayHello
(HelloRequest) returns (HelloReply) {}
-
}
-
-
message HelloRequest {
-
string
name
=
1;
-
}
-
-
message HelloReply {
-
string
message
=
1;
-
}
执行命令
ThirdParty\grpc_build\bin\protoc.exe -IGrpcLibrary --cpp_out GrpcLibrary GrpcLibrary\HelloWorld.proto --grpc_out GrpcLibrary --plugin=protoc-gen-grpc=ThirdParty\grpc_build\bin\grpc_cpp_plugin.exe
命令执行成功后,GrpcLibrary目录下会生成HelloWorld.grpc.pb.cc、HelloWorld.grpc.pb.h、HelloWorld.pb.cc和HelloWorld.pb.h
将其都添加到项目GrpcLibrary中。最后GrpcClient、GrpcServer分别引用类库GrpcLibrary。
3.服务端
-
// greeter_server.cc
-
#include <iostream>
-
#include <memory>
-
#include <string>
-
-
#include <grpcpp/grpcpp.h>
-
-
#ifdef BAZEL_BUILD
-
#include "examples/protos/helloworld.grpc.pb.h"
-
#else
-
#include "HelloWorld.grpc.pb.h"
-
#endif
-
-
using grpc::Server;
-
using grpc::ServerBuilder;
-
using grpc::ServerContext;
-
using grpc::Status;
-
using GrpcLibrary::HelloRequest;
-
using GrpcLibrary::HelloReply;
-
using GrpcLibrary::GrpcService;
-
-
// Logic and data behind the server's behavior.
-
class
GreeterServiceImpl
final :
public GrpcService::Service {
-
Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override
-
{
-
std::string prefix("Hello ");
-
reply->
set_message(prefix + request->
name());
-
return Status::OK;
-
}
-
};
-
-
void RunServer() {
-
std::string server_address("0.0.0.0:50051");
-
GreeterServiceImpl service;
-
-
ServerBuilder builder;
-
// Listen on the given address without any authentication mechanism.
-
builder.
AddListeningPort(server_address, grpc::
InsecureServerCredentials());
-
// Register "service" as the instance through which we'll communicate with
-
// clients. In this case it corresponds to an *synchronous* service.
-
builder.
RegisterService(&service);
-
// Finally assemble the server.
-
std::unique_ptr<Server> server(builder.BuildAndStart());
-
std::cout <<
"Server listening on " << server_address << std::endl;
-
-
// Wait for the server to shutdown. Note that some other thread must be
-
// responsible for shutting down the server for this call to ever return.
-
server->
Wait();
-
}
-
-
int main(int argc, char** argv) {
-
RunServer();
-
-
return
0;
-
}
4.客户端
-
// greeter_client.cc
-
#include <iostream>
-
#include <memory>
-
#include <string>
-
-
#include <grpcpp/grpcpp.h>
-
-
#ifdef BAZEL_BUILD
-
#include "examples/protos/helloworld.grpc.pb.h"
-
#else
-
#include "helloworld.grpc.pb.h"
-
#endif
-
-
using grpc::Channel;
-
using grpc::ClientContext;
-
using grpc::Status;
-
using GrpcLibrary::HelloRequest;
-
using GrpcLibrary::HelloReply;
-
using GrpcLibrary::GrpcService;
-
-
class
GreeterClient {
-
public:
-
GreeterClient(std::shared_ptr<Channel> channel)
-
:
stub_(GrpcService::
NewStub(channel)) {}
-
-
-
std::string SayHello(const std::string& user) {
-
// Data we are sending to the server.
-
HelloRequest request;
-
request.
set_name(user);
-
-
// Container for the data we expect from the server.
-
HelloReply reply;
-
-
// Context for the client. It could be used to convey extra information to
-
// the server and/or tweak certain RPC behaviors.
-
ClientContext context;
-
-
// The actual RPC.
-
Status status = stub_->
SayHello(&context, request, &reply);
-
-
// Act upon its status.
-
if (status.
ok()) {
-
return reply.
message();
-
}
-
else {
-
std::cout << status.
error_code() <<
": " << status.
error_message()
-
<< std::endl;
-
return
"RPC failed";
-
}
-
}
-
-
private:
-
std::unique_ptr<GrpcService::Stub> stub_;
-
};
-
-
int main(int argc, char** argv) {
-
-
GreeterClient greeter(grpc::CreateChannel(
-
"localhost:50051", grpc::InsecureChannelCredentials()));
-
std::string user("world");
-
std::string reply = greeter.
SayHello(user);
-
std::cout <<
"Greeter received: " << reply << std::endl;
-
-
return
0;
-
}
5.测试
先启动服务的,再启动客户端。