客户端有几点说明
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