diff --git a/muduo/net/protorpc/RpcChannel.cc b/muduo/net/protorpc/RpcChannel.cc index d18e081fc..b510ae614 100644 --- a/muduo/net/protorpc/RpcChannel.cc +++ b/muduo/net/protorpc/RpcChannel.cc @@ -135,8 +135,9 @@ void RpcChannel::onRpcMessage(const TcpConnectionPtr& conn, google::protobuf::Message* response = service->GetResponsePrototype(method).New(); // response is deleted in doneCallback int64_t id = message.id(); + doneCallbackArg arg{response, id}; service->CallMethod(method, NULL, get_pointer(request), response, - NewCallback(this, &RpcChannel::doneCallback, response, id)); + NewCallback(&RpcChannel::doneCallback, std::weak_ptr(shared_from_this()), arg)); error = NO_ERROR; } else @@ -172,13 +173,17 @@ void RpcChannel::onRpcMessage(const TcpConnectionPtr& conn, } } -void RpcChannel::doneCallback(::google::protobuf::Message* response, int64_t id) +void RpcChannel::doneCallback(const std::weak_ptr wkChannel, const doneCallbackArg arg) { - std::unique_ptr d(response); - RpcMessage message; - message.set_type(RESPONSE); - message.set_id(id); - message.set_response(response->SerializeAsString()); // FIXME: error check - codec_.send(conn_, message); + std::unique_ptr d(arg.response); + RpcChannelPtr channel(wkChannel.lock()); + if (channel) + { + RpcMessage message; + message.set_type(RESPONSE); + message.set_id(arg.id); + message.set_response(arg.response->SerializeAsString()); // FIXME: error check + channel->codec_.send(channel->conn_, message); + } } diff --git a/muduo/net/protorpc/RpcChannel.h b/muduo/net/protorpc/RpcChannel.h index 172b41ebe..3f8816c4a 100644 --- a/muduo/net/protorpc/RpcChannel.h +++ b/muduo/net/protorpc/RpcChannel.h @@ -88,7 +88,8 @@ namespace net // RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234"); // MyService* service = new MyService::Stub(channel); // service->MyMethod(request, &response, callback); -class RpcChannel : public ::google::protobuf::RpcChannel +class RpcChannel : public ::google::protobuf::RpcChannel, + public std::enable_shared_from_this { public: RpcChannel(); @@ -123,11 +124,17 @@ class RpcChannel : public ::google::protobuf::RpcChannel Timestamp receiveTime); private: + struct doneCallbackArg + { + ::google::protobuf::Message* response; + int64_t id; + }; + void onRpcMessage(const TcpConnectionPtr& conn, const RpcMessagePtr& messagePtr, Timestamp receiveTime); - void doneCallback(::google::protobuf::Message* response, int64_t id); + static void doneCallback(const std::weak_ptr wkChannel, const doneCallbackArg arg); struct OutstandingCall {