C++实现gRPC异步双向流式的客户端和服务端(二)

下面是服务端的实现,主要逻辑是参考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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值