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));

最新文章

  1. Android Notification 详解(一)——基本操作
  2. javascript数据结构与算法---栈
  3. 水果项目第2集-建立数据库-&gt;编写数据访问基础类-&gt;实现类的方法-&gt;调试通过
  4. DFS POJ 2362 Square
  5. swift 中异常的处理方法
  6. js对象序列化JSON.stringify()与反序列化JSON.parse()
  7. 用Delphi直接获取bmp图片的像素
  8. OCP读书笔记(27) - 题库(ExamG)
  9. 移植X264成功
  10. 让png在ie下正常显示 用到了jquery插件DD_belatedPNG 但是在ie6中这句话 前面添加有效 后面移除无效 IE6 jq removeClass无效
  11. radiobutton以及checkbox背景图片拉伸变形的问题
  12. Javascript和JQuery中常用的随机数产生函数
  13. 对stm32寄存器的理解(个人理解,大神轻喷)
  14. [蓝桥杯]PREV-10.历届试题_幸运数
  15. OneNET麒麟座应用开发之八:采集大气压力等环境参数
  16. Oracle11g温习-第十一章:管理undo
  17. nginx 重写URL尾部斜杠
  18. EayRadius 于 2013-7-19 进行体验度更新,增加用户体验度
  19. 转:AMD规范与CMD规范的区别是什么?
  20. SpringBoot入门 (二) 属性文件读取

热门文章

  1. iOS内置图片瘦身思路整理
  2. netty常用使用方式
  3. 动态加载js css 插件
  4. MSSQL 常用操作
  5. JS获取DOM元素
  6. .Net中各种不同的对象创建方式的速度差异
  7. How To Use Linux epoll with Python
  8. github设置
  9. APP后台API文档管理对接(APP后台框架五)
  10. java线程相关