具体参数的写入函数根据参数的类型具体处理并写入到服务器端。这样整个函数 调用就做完了,剩下的就是处理写入后的一些善后处理,看具体代码有注释。
当函数 调用的消息发送出去以后就开始准备接收函数远程调用的结果(异步调用除外),这里接收 Log函数调用返回结果的函数是recv_log,代码如下:
ResultCode
scribeClient::recv_Log()
{
int32_t rseqid = 0;
std::string fname;
::apache::thrift::protocol::TMessageType mtype;//接收返回消息的类型
iprot_->readMessageBegin(fname, mtype, rseqid);//读取返回结果的消息
if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {//处理返回消息是异常的情况
::apache::thrift::TApplicationException x;
x.read(iprot_);//读取异常信息
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
throw x;//抛出异常信息
}
if (mtype != ::apache::thrift::protocol::T_REPLY) {//处理不是正常回复的结果
iprot_->skip(::apache::thrift::protocol::T_STRUCT);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
}
if (fname.compare("Log") != 0) {//比较是否是Log函数调用返回的结果
iprot_->skip(::apache::thrift::protocol::T_STRUCT);
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
}
ResultCode _return;
scribe_Log_presult result;
result.success = &_return;
result.read(iprot_);//读取结果信息
iprot_->readMessageEnd();
iprot_->getTransport()->readEnd();
if (result.__isset.success) {//成功就正常返回,否则抛出异常信息
return _return;
}
throw ::apache::thrift::TApplicationException
(::apache::thrift::TApplicationException::MISSING_RESULT,
"Log failed: unknown result");//抛出不知道结果的异常信息,调用失败了
}
接收RPC调用结果的函数都是根据返回消息的类型做相应处理,不成功就抛出相应 的异常信息。首先这里调用二进制协议的readMessageBegin函数读取由二进制写入的消息( 这个当然是服务器端写入的),这个函数代码实现如下:
template <class
Transport_>
uint32_t TBinaryProtocolT<Transport_>::readMessageBegin(std::string&
name,
TMessageType& messageType, int32_t& seqid) {
uint32_t result = 0;
int32_t sz;
result += readI32(sz);//读取消息的头部(可能是协议版本号和消息类型的组合,也可能直接是消息)
if (sz < 0) {//如果小于0(就是二进制为第一位以1开头,说明是带有协议版本号的
// Check for correct version number
int32_t version = sz & VERSION_MASK;//取得消息的版本号
if (version != VERSION_1) {//如果不匹配二进制协议的版本号就抛出一个坏的协议异常
throw TProtocolException(TProtocolException::BAD_VERSION, "Bad version identifier");
}
messageType = (TMessageType)(sz & 0x000000ff);//取得消息类型
result += readString(name);//取得消息名称(也就是函数名称)
result += readI32(seqid);//取得函数调用ID号
} else {
if (this->strict_read_) {//要求读协议本版号,但是这种情况是不存在协议版本号的所以抛出异常
throw TProtocolException(TProtocolException::BAD_VERSION,
"No version identifier... old protocol client in strict mode?");
} else {
int8_t type;
result += readStringBody(name, sz);//读取消息名称(也就是函数名称)
result += readByte(type);//读取消息类型
messageType = (TMessageType)type;
result += readI32(seqid);//读取函数调用ID号
}
}
return result;//f返回读取数据的长度
}
http://www.bianceng.cn/a/2014/0215/39708_3.htm

本文详细解析了Thrift RPC机制中的函数调用流程,包括参数的写入、远程调用结果的接收及异常处理等内容,并深入介绍了二进制协议的读取过程。
6076

被折叠的 条评论
为什么被折叠?



