具体参数的写入函数根据参数的类型具体处理并写入到服务器端。这样整个函数 调用就做完了,剩下的就是处理写入后的一些善后处理,看具体代码有注释。
当函数 调用的消息发送出去以后就开始准备接收函数远程调用的结果(异步调用除外),这里接收 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