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

客户端有几点说明
1.回调对象用的对象的函数指针,形如connected_func_=std::bind(&AsyncClientBidiStreamImpl::Connected, this, std::placeholders::_1),没有用状态机变量控制异步回调,
因为如果用状态变量控制,连续调用两次不同api并需要传入调用对象时没法实现,比如        
obj.statu = DISCONNECT;
stream_->Finish(&status_, &obj);
obj.statu = READ_DONE;
stream_->Read(&status_, &obj);
这种写法就会有问题,变量statu的值会被第二次调用给覆盖为READ_DONE,起不到状态流转的作用了。
2.发送请求时候进行连接调用,因为我这边需求是请求地址不能提前知道,只有在请求时才能知道地址,这块实现当时遇到一些坑需要注意,连接失败重试的时候必须是新的调用对象
3.客户端是有缓存stub对象,起到重用连接的作用

Client.cpp

#include <iostream>
#include "Client.h"
#include "RpcClient.h"
#include "Common.h"
#include "LuaInterface.h"
#include "Log.h"

int32_t AsyncClientBidiStreamImpl::object_count_ = 0;

AsyncClientBidiStreamImpl::AsyncClientBidiStreamImpl(RpcClient* rpc, 
    CompletionQueue* cq, CommonService::Stub* stub,
    std::function<void(grpc::Status, CommonResponse*)> callback)
    :context_(new ClientContext),
    rpc_(rpc),
    callback_(callback),
    stub_(stub),
    cq_(cq),
    response_(),
    connected_func_(std::bind(&AsyncClientBidiStreamImpl::Connected, this, std::placeholders::_1)),
    write_done_func_(std::bind(&AsyncClientBidiStreamImpl::WriteDone, this, std::placeholders::_1)),
    read_done_func_(std::bind(&AsyncClientBidiStreamImpl::ReadDone, this, std::placeholders::_1)),
    disconnect_func_(std::bind(&AsyncClientBidiStreamImpl::Disconnect, this, std::placeholders::_1)),
    call_id_(UniqueIdGenerator::GetInstance().GetUniqueId())
{
    object_count_++;
    //ConfigSetting::InitAsyncContext(context_.get(), rpc->GetChannelMgr()->GetAsyncTimeOut());

    Start();
}

void AsyncClientBidiStreamImpl::Start()
{
    stream_ = stub_->AsyncSendBidiStreamMsg(context_.get(), cq_, &connected_func_);
    is_need_reset_ = false;
}

bool AsyncClientBidiStreamImpl::Connected(bool ok)
{
    if (ok)
    {

        is_connected = true;

        if (!stream_)
        {
            return false;
        }

        stream_->Finish(&status_, &disconnect_func_);
        stream_->Read(&response_, &read_done_func_);
        


        if(!queueReq.empty())
        {
            if (!is_writting_)
            {
                auto req = queueReq.front();

                queueReq.pop_front();

                is_writting_ = true;

                stream_->Write(req, &write_done_func_);

  &n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值