下面是服务端的实现,主要逻辑是参考gRPC源码里的测试用例
grpc-framework-master\test\cpp\qps\server_async.cc,
代码没有贴全,比如主循环和调用,main函数中形如 while (is_loop)
{
rpc_server_->RunOnce();
}这样就可以,同时rpc_server_.init()必须提前调用。
有几点说明:
1.RPCRecorder这个类是为了便于lua端控制调用对象结束的,不需要的可以忽略;
2.我这边的框架需求是业务线程尽量用一个,也就是不另外自己开线程,基于此就设计了主循环使用AsyncNext()的非阻塞调用,同时程序中的客户端和服务端共用一个CompleteQueue,这种写法目前网上不多见,经过测试目前没出现什么问题;
3.还有个待解决的问题,由于我们希望框架程序使用尽量少的线程,是出于考虑集群部署的资源利用率,但是gRPC自身线程数目前查看达到了27个左右,代码中下列几行初衷是想设置线程数,但是实际并没有起作用,目前版本应该是没有可以直接控制的接口,可能需要修改gRPC源码来解决。
int maxThreadNum = maxThread;
builder_->SetResourceQuota(
grpc::ResourceQuota("CommonService").SetMaxThreads(maxThreadNum));
builder_->SetSyncServerOption(ServerBuilder::SyncServerOption::MIN_POLLERS, 1);
builder_->SetSyncServerOption(ServerBuilder::SyncServerOption::MAX_POLLERS, 1);
builder_->SetSyncServerOption(ServerBuilder::SyncServerOption::NUM_CQS, 1);
ServerCallImpl.h
#pragma once
#include <algorithm>
#include <forward_list>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
#include <string>
#include <grpcpp/grpcpp.h>
#include <grpcpp/alarm.h>
#include "common_service.grpc.pb.h"
#include "IRpcCall.h"
typedef xengine::CommonService::AsyncService ServiceType;
using grpc::ServerContext;
using grpc::CompletionQueue;
using grpc::ServerCompletionQueue;
using grpc::ServerAsyncResponseWriter;
using grpc::ServerAsyncReader;
using grpc::ServerAsyncWriter;
using grpc::ServerAsyncReaderWriter;
using grpc::Status;
using grpc::Alarm;
using NextCallFunc = std::function<bool(bool)>;
//定时器
class ServerAlarm final : public IRpcCall
{
public:
ServerAlarm(std::function<void()>&& call);
~ServerAlarm() override;
void Reset() override;
bool AlarmDone(bool ok);
void Set(grpc::CompletionQueue* cq, const gpr_timespec& deadline);
void Set(grpc::CompletionQueue* cq, int64_t ms);
private:
NextCallFunc alarm_done_func_;
Alarm alarm_;
std::function<void()> callback_;
};
//单向问答
class ServerCallUnaryImpl final : public IRpcCall
{
using Method_Func = std::function<void(ServerContext*, CommonRequest*,
grpc::ServerAsyncResponseWriter<CommonResponse>*, void*)>;
public:
ServerCallUnaryImpl(Method_Func request_method,ServiceType* svc,grpc::ServerCompletionQueue* cq);
~ServerCallUnaryImpl() override {}
void Reset() override;
void CallLuaProcess(grpc::Status& status);
void Response(CommonResponse& resp,bool reset) override;
private:
bool Finisher(bool ok);
bool Invoker(bool ok);
void makeNew();
std::unique_ptr<ServerContext> srv_ctx_;
CommonRequest req_;
NextCallFunc finish_func_;
NextCallFunc invoke_func_;
std::function<void(ServerConte