1.首先编写proto文件;
GrpcTest.proto内容如下:
syntax = "proto3";
package GrpcTestCalc;
service Caltulator {
rpc AddResult(Request) returns (Response) {}
rpc SubResult(Request) returns (Response) {}
}message Request {
int32 numA = 1;
int32 numB = 2;
}message Response {
int32 result = 1;
}
对该文件单独进行编译,产生grpc相关的四个文件;
2.编写grpc服务端代码;
GrpcTestMain.cpp内容如下:
/*
tfk 2018.09.06
*/#include
#include
#include
#include
#include#include
#include#include "GrpcTest.grpc.pb.h"
using grpc::Server;
using grpc::ServerAsyncResponseWriter;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::ServerCompletionQueue;
using grpc::Status;
using GrpcTestCalc::Request;
using GrpcTestCalc::Response;
using GrpcTestCalc::Caltulator;
class ServerImpl final {
public:
~ServerImpl() {
server_->Shutdown();
cq_->Shutdown();
}void Run() {
std::string server_address("x.x.x.x:port");
ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service_);
cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
std::cout << "Server listening on " << server_address << std::endl;/*for (int i = 0; i < 8; i++)
{
_beginthreadex(NULL,
0,
ServerImpl::ThreadHandlerRPC,
(void*)this,
0,
0);
}*/HandleRPCS();
}
private:
class CallData {
public:
enum ServiceType {
SS_AddStudent = 0,
SS_SubTeacher
};public:
CallData(Caltulator::AsyncService* service, ServerCompletionQueue* cq, ServiceType s_type)
:service_(service), cq_(cq), s_type_(s_type), add_responder_(&ctx_), sub_responder_(&ctx_), status_(CREATE) {
Process();
}void Process() {
if (status_ == CREATE)
{
status_ = PROCESS;
switch (s_type_)
{
case ServerImpl::CallData::SS_AddStudent:
service_->RequestAddResult(&ctx_, &add_request, &add_responder_, cq_, cq_, this);
break;
case ServerImpl::CallData::SS_SubTeacher:
service_->RequestSubResult(&ctx_, &sub_request, &sub_responder_, cq_, cq_, this);
break;
default:
break;
}
}
else if (status_ == PROCESS) {
status_ = FINISH;
new CallData(service_, cq_, this->s_type_);
switch (s_type_)
{
case ServerImpl::CallData::SS_AddStudent:
{
add_reply_.set_result(add_request.numa() + add_request.numb());status_ = FINISH;
add_responder_.Finish(add_reply_, Status::OK, this);
}
break;
case ServerImpl::CallData::SS_SubTeacher:
{
sub_reply_.set_result(sub_request.numa() - sub_request.numb());status_ = FINISH;
sub_responder_.Finish(sub_reply_, Status::OK, this);
}
break;
default:
break;
}
}
else {
GPR_ASSERT(status_ == FINISH);
delete this;
}}
private:
Caltulator::AsyncService* service_;
ServerCompletionQueue* cq_;
ServerContext ctx_;
ServiceType s_type_;Request add_request;
Response add_reply_;
ServerAsyncResponseWriteradd_responder_; Request sub_request;
Response sub_reply_;
ServerAsyncResponseWritersub_responder_; enum CallStatus {
CREATE,
PROCESS,
FINISH
};
CallStatus status_;
};private:
/*static unsigned __stdcall ThreadHandlerRPC(void* lparam) {
ServerImpl* impl = (ServerImpl*)lparam;
impl->HandleRPCS();
return 1;
}*/void HandleRPCS() {
new CallData(&service_, cq_.get(), ServerImpl::CallData::SS_AddStudent);
new CallData(&service_, cq_.get(), ServerImpl::CallData::SS_SubTeacher);
void* tag;
bool ok;
while (true) {
GPR_ASSERT(cq_->Next(&tag, &ok));
GPR_ASSERT(ok);
static_cast(tag)->Process();
}
}
private:
std::shared_ptrcq_;
Caltulator::AsyncService service_;
std::shared_ptrserver_;
};
int main()
{
ServerImpl server;
server.Run();return 0;
}
上述代码为服务端代码,客户端代码较简单,不做累述。