流程图示
- 通过编解码器完成解码
- 通过nettyClientHander衔接dubbohandler和netty handler
- nettyClient 作用dubbo handler 的总入口触发MultiMessageHandler到HandlerExchangeHandler的调用
- HandlerExchangeHandler为消费者接收响应的调用终止,比服务端接收request的处理少一步dubboProtocol.requestHandler处理
HeaderExchangeHandler.handleResponse一消费者接收响应
- 从编解码到nettyClientHandler到nettyClient到MultiMessageHandler…DecodeHandler流程与提供者接收request消息流程基本一致,不在重复叙述
- 区别就是nettyClient与NettyServer不同,功能基本一致
- 处理响应
- 通过Response.id获取DefaultFuture
- 设置DefaultFuture.complete为res.getResult
- 激活AsyncToSyncInvoker的asyncResult.get
- 返回biz层dubbo接口的值
static void handleResponse(Channel channel, Response response) throws RemotingException {
if (response != null && !response.isHeartbeat()) {
通过id 交给 DefaultFuture完成请求响应
DefaultFuture.received(channel, response);
}
}
public static void received(Channel channel, Response response) {
received(channel, response, false);
}
public static void received(Channel channel, Response response, boolean timeout) {
try {
获取Response的id 根据id获取future [future 在消费者发送request时设置,并且id为request.id]
request到达服务提供者时,服务提供者构建Response,设置Response.id = request.id
服务提供者发送Response到消费者
所以这里根据Response.id能获取原来构建的future对象
DefaultFuture future = FUTURES.remove(response.getId());
if (future != null) {
Timeout t = future.timeoutCheckTask;
if (!timeout) {
t.cancel();
}
future接收response会取消AsyncToSyncInvoker.get的阻塞
业务线程便获取到了Response[rpc层在对Response进行一些处理转成业务接口的目标对象]
设置DefaultFuture.complete为res.getResult()
future.doReceived(response);
} else {
...... 删除日志代码
}
} finally {
CHANNELS.remove(response.getId());
}
}
图解
总结
- 至此.概述了消费者到服务提供者的远程通信rpc-remote架构模型