gRPC异步处理应答

gRPC异步处理应答

(金庆的专栏)

gRPC的示例 greeter_async_client.cc 不算是异步客户端,
它使用了异步请求,但是阻塞式等待应答,结果成为一个同步调用。

  std::string SayHello(const std::string& user) {
    ...
    std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
        stub_->AsyncSayHello(&context, request, &cq));
    rpc->Finish(&reply, &status, (void*)1);
    void* got_tag;
    bool ok = false;
    // Block until the next result is available in the completion queue "cq".
    cq.Next(&got_tag, &ok);

    ...
    return reply.message();
  }

为了实现真正的异步RPC请求,发出请求后立即返回,然后在一个线程中处理所有应答。
以下代码经测试表明可以使用。  

// Grpc异步应答处理,线程中运行.
void HandleGrpcResponses()
{
    ...
    grpc::CompletionQueue & rCq = rMgr.GetCq();
    for (;;)
    {
        void * pTag;
        bool ok = false;
        // Block until the next result is available in the completion queue "cq".
        rCq.Next(&pTag, &ok);

        // Act upon the status of the actual RPC.
        std::unique_ptr<IGrpcCb> pCb(static_cast<IGrpcCb*>(pTag));
        const grpc::Status & rStatus = pCb->GetStatus();
        if (rStatus.ok())
            (*pCb)();  // run callback
    }
}

IGrpcCb是回调类,定义如下:

class IGrpcCb
{
public:
    explicit IGrpcCb(...) {};
    virtual ~IGrpcCb(void) {};

    grpc::ClientContext & GetContext() { return m_context; }
    grpc::Status & GetStatus() { return m_status; }

public:
    virtual void operator()() {};

protected:
    grpc::ClientContext m_context;
    grpc::Status m_status;
    ...
};

// R is response class like rpc::CreateRoomResponse.
template <class R>
class GrpcCb final : public IGrpcCb
{
public:
    explicit GrpcCb(...)
        : IGrpcCb(...)
        {};
    virtual ~GrpcCb(void) override {};

public:
    typedef std::unique_ptr<grpc::ClientAsyncResponseReader<R> > RpcPtr;

public:
    R & GetResp() { return m_resp; }
    void SetRpcPtrAndFinish(RpcPtr pRpc)
    {
        m_pRpc.swap(pRpc);
        m_pRpc->Finish(&m_resp, &m_status, (void*)this);
    }

public:
    virtual void operator()() override
    {
        // Deal m_resp...
    }

private:
    RpcPtr m_pRpc;
    R m_resp;
};

异步请求代码示例如下:

        grpc::CompletionQueue & cq = GetCq();
        rpc::CreateRoomRequest req;

        // pGcb will be deleted in HandleGrpcResponses().
        auto pGcb = new GrpcCb<rpc::CreateRoomResponse>(...);
        pGcb->SetRpcPtrAndFinish(
            m_pStub->AsyncCreateRoom(&pGcb->GetContext(), req, &cq));



  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值