netty是在nio基础上包装的。
我们拿些案例使用。
代码:
我们先看这两个的源码源码
我们重点分析这两句话:
打断点执行一下我们:
我们看下其实这个是线程组:
我们看下这句话:
追进去:
在这里进行了初始化了。
这里得到最大值。
我们再往下追到这里:
这是开始的。
我们看下依赖关系:
这时我们看真实的类型:
我们看下继承关系:
再往下:
加监听器。
-------------------
再下断点:
进入这个Group
我们看下channel是在什么时候创建的。
channelFactory反射创建NioSocketChannel。
我们看下bind方法:
一直追:
此时这个channel是NioServerSocketChannel。
--------------------------------92-------------------------------------------
我们重点看下这个方法:
参数:
创建指定线程数的执行器数组。
初始化线程
为每一个单例的线程池添加一个关闭的监听器。
讲所有的单例线程池添加到set中去。
---
我们再看一段代码:
进去有很多属性。
参数是怎么管理的?
options是什么?
--------------------------------93-------------------------------------------
重点,我们看绑定端口是怎么做到的?
其有两个核心的方法:
和
我们先看下doBind方法,返回的是一个异步执行的结果。
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
channel = channelFactory.newChannel();// 这个是创建
init(channel);
} catch (Throwable t) {
if (channel != null) {
// channel can be null if newChannel crashed (eg SocketException("too many open files"))
channel.unsafe().closeForcibly();
// as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
}
// as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
return new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE).setFailure(t);
}
ChannelFuture regFuture = config().group().register(channel);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
channel.unsafe().closeForcibly();
}
}
return regFuture;
}
接下来看下init方法:
可以看到添加handler时候先创建context,然后把context加入到链表的尾部。
private void addLast0(AbstractChannelHandlerContext newCtx) {
AbstractChannelHandlerContext prev = tail.prev;
newCtx.prev = prev;
newCtx.next = tail;
prev.next = newCtx;
tail.prev = newCtx;
}
------------------------
我们在doBind追:
private ChannelFuture doBind(final SocketAddress localAddress) {
final ChannelFuture regFuture = initAndRegister();
final Channel channel = regFuture.channel();
if (regFuture.cause() != null) {
return regFuture;
}
if (regFuture.isDone()) {
// At this point we know that the registration was complete and successful.
ChannelPromise promise = channel.newPromise();
doBind0(regFuture, channel, localAddress, promise);
return promise;
} 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 {
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();
doBind0(regFuture, channel, localAddress, promise);
}
}
});
return promise;
}
}
我们一直往下追可以追到
一直追:
--------------------------------94-------------------------------------------