connect方法调用如下方法,值得分析
private ChannelFuture doResolveAndConnect(final SocketAddress remoteAddress, final SocketAddress localAddress) {
final ChannelFuture regFuture = initAndRegister();
final Channel channel = regFuture.channel();
if (regFuture.isDone()) {
if (!regFuture.isSuccess()) {
return regFuture;
}
return doResolveAndConnect0(channel, remoteAddress, localAddress, channel.newPromise());
} else {
// Registration future is almost always fulfilled already, but just in case it's not.
final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
regFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
// Direclty obtain the cause and do a null check so we only need one volatile read in case of a
// failure.
Throwable cause = future.cause();
if (cause != null) {
// Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an
// IllegalStateException once we try to access the EventLoop of the Channel.
promise.setFailure(cause);
} else {
// Registration was successful, so set the correct executor to use.
// See https://github.com/netty/netty/issues/2586
promise.registered();
doResolveAndConnect0(channel, remoteAddress, localAddress, promise);
}
}
});
return promise;
}
}
initAndRegister:
channel实例化:ReflectiveChannelFactory反射调用
初始化:ChannelInitalizer加入pipeline,ChannelConfig 填充(来源于BootStrap),属性填充(来源于BootStrap)
注册:生成DefaultChannelPromise,选择EventLoopGroup内的EventLoop(此时Channel的EventLoop就定下来了),提交register任务(channel注册到刚选出的EventLoop的selector上,不关注任何事件)到对应EventLoop,返回DefaultChannelPromise(ChannelFuture)
1 注册过程先选定特定的EventLoop,线程返回,由EventLoop完成实际注册并通知,若已完成且失败,返回用户,若已完成且成功,返回connect的future(新建)给用户,此时connect可能还没完成
2 若注册未完成,返回PendingRegistrationPromise给用户,注册future的Listener通知PendingRegistrationPromise给到用户,避免用户也给注册future加listener,导致还未connect便先执行用户的listener