baidu_rpc协议在void ProcessRpcRequest(InputMessageBase* msg_base)函数最后有SendRpcResponse,如下:
// `cntl', `req' and `res' will be deleted inside `SendRpcResponse'
// `socket' will be held until response has been sent
SendRpcResponse(meta.correlation_id(), cntl.release(),
req.release(), res.release(), server,
method_status, msg->received_us());
这个是前面都没有调用方法发送,就调用最后这个发送。
但是到了NsHead协议函数最后就没有SendNsHeadResponse了,靠NsheadClosure 析构时发送出去
在ProcessNsHeadRequest函数中有代码:
NsheadClosure* nshead_done = new (space) NsheadClosure(sub_space);
Controller* cntl = &(nshead_done->_controller);
NsheadMessage* req = &(nshead_done->_request);
NsheadMessage* res = &(nshead_done->_response);//res在你的method赋值
析构函数中调用NsheadClosure::Run
void NsheadClosure::Run() {
// Recycle itself after `Run'
std::unique_ptr<NsheadClosure, DeleteNsheadClosure> recycle_ctx(this);
ControllerPrivateAccessor accessor(&_controller);
Span* span = accessor.span();
if (span) {
span->set_start_send_us(butil::cpuwide_time_us());
}
Socket* sock = accessor.get_sending_socket();
MethodStatus* method_status = _server->options().nshead_service->_status;
ConcurrencyRemover concurrency_remover(method_status, &_controller, _received_us);
if (!method_status) {
// Judge errors belongings.
// may not be accurate, but it does not matter too much.
const int error_code = _controller.ErrorCode();
if (error_code == ENOSERVICE ||
error_code == ENOMETHOD ||
error_code == EREQUEST ||
error_code == ECLOSE ||
error_code == ELOGOFF ||
error_code == ELIMIT) {
ServerPrivateAccessor(_server).AddError();
}
}
if (_controller.IsCloseConnection()) {
sock->SetFailed();
return;
}
if (_do_respond) {
// response uses request's head as default.
// Notice that the response use request.head.log_id directly rather
// than _controller.log_id() which may be different and packed in
// the meta or user messages.
_response.head = _request.head;
_response.head.magic_num = NSHEAD_MAGICNUM;
_response.head.body_len = _response.body.length();
if (span) {
int response_size = sizeof(nshead_t) + _response.head.body_len;
span->set_response_size(response_size);
}
butil::IOBuf write_buf;
write_buf.append(&_response.head, sizeof(nshead_t));
write_buf.append(_response.body.movable());
// Have the risk of unlimited pending responses, in which case, tell
// users to set max_concurrency.
Socket::WriteOptions wopt;
wopt.ignore_eovercrowded = true;
if (sock->Write(&write_buf, &wopt) != 0) {
const int errcode = errno;
PLOG_IF(WARNING, errcode != EPIPE) << "Fail to write into " << *sock;
_controller.SetFailed(errcode, "Fail to write into %s",
sock->description().c_str());
return;
}
}
if (span) {
// TODO: this is not sent
span->set_sent_us(butil::cpuwide_time_us());
}
}