ServerBootstrap的成员变量
//worker group
private volatile EventLoopGroup childGroup;
//设置进来的childHandler
private volatile ChannelHandler childHandler;
AbstractBootstrap:
/**
* EventLoopGroup 对象 boss group
*/
volatile EventLoopGroup group;
/**
* channel工厂用于创建channel
*/
@SuppressWarnings("deprecation")
private volatile ChannelFactory extends C> channelFactory;
/**
* 本地地址
*/
private volatile SocketAddress localAddress;
/**
* 可选项集合
*/
private final Map, Object> options = new LinkedHashMap, Object>();
/**
* 属性集合
*/
private final Map, Object> attrs = new LinkedHashMap, Object>();
/**
* 启动的时候设置的处理器 .handler(new LoggingHandler(LogLevel.INFO))
* 设置进来的
*/
private volatile ChannelHandler handler;
先看服务端启动的代码
//创建boss worker线程
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
final EchoServerHandler serverHandler = new EchoServerHandler();
try {
//创建netty服务端启动器
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)//给启动器配置boss worker
.channel(NioServerSocketChannel.class)//设置使用NioServerSocketChannel
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
//p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(serverHandler);
}
});
io.netty.bootstrap.ServerBootstrap#group(io.netty.channel.EventLoopGroup,io.netty.channel.EventLoopGroup)
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
super.group(parentGroup);
if (childGroup == null) {
throw new NullPointerException("childGroup");
}
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
}
//保存到worker group
this.childGroup = childGroup;
return this;
}
public B group(EventLoopGroup group) {
if (group == null) {
throw new NullPointerException("group");
}
if (this.group != null) {//不允许重复设置
throw new IllegalStateException("group set already");
}
//保存到boss group
this.group = group;
return self();
}
io.netty.bootstrap.AbstractBootstrap#channel
/**
* 设置要被实例化的 Channel 的类
*/
public B channel(Class extends C> channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
}
return channelFactory(new ReflectiveChannelFactory(channelClass));
}
ReflectiveChannelFactory工厂,用于反射生产channel对象
public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {
//Channel 对应的类
private final Class extends T> clazz;
public ReflectiveChannelFactory(Class extends T> clazz) {
if (clazz == null) {
throw new NullPointerException("clazz");
}
this.clazz = clazz;
}
@Override
public T newChannel() {
try {
// 反射调用默认构造方法,创建 Channel 对象
return clazz.getConstructor().newInstance();
} catch (Throwable t) {
throw new ChannelException("Unable to create Channel from class " + clazz, t);
}
}
这个工厂模式一目了然
io.netty.bootstrap.AbstractBootstrap#handler(io.netty.channel.ChannelHandler)
/**
* the {@link ChannelHandler} to use for serving the requests.
* 设置创建 Channel 的处理器
*/
public B handler(ChannelHandler handler) {
if (handler == null) {
throw new NullPointerException("handler");
}
//保存处理器
this.handler = handler;
return self();
}
public ServerBootstrap childHandler(ChannelHandler childHandler) {
if (childHandler == null) {
throw new NullPointerException("childHandler");
}
//保存到childHandler处理器
this.childHandler = childHandler;
return this;
}
io.netty.bootstrap.AbstractBootstrap#bind(int)根据调用链,最后走到
.bootstrap.AbstractBootstrap#doBind
private ChannelFuture doBind(final SocketAddress localAddress) {
// 初始化并注册一个 Channel 对象,因为注册是异步的过程,所以返回一个 ChannelFuture 对象。
final ChannelFuture regFuture = initAndRegister();
final Channel channel = regFuture.channel();
if (regFuture.cause() != null) {// 若发生异常,直接进行返回
return regFuture;
}
// 绑定 Channel 的端口,并注册 Channel 到 SelectionKey 中。
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;
}
}
io.netty.bootstrap.AbstractBootstrap#initAndRegister
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
// 创建 Channel 对象(工厂模式反射创建)
channel = channelFactory.newChannel();
// 初始化 Channel 配置
init(channel);
} catch (Throwable t) {
if (channel != null) {// 已创建 Channel 对象
channel.unsafe().closeForcibly();// 强制关闭 Channel
/**
* 因为创建 Channel 对象失败,所以需要创建一个 FailedChannel 对象,设置到 DefaultChannelPromise 中才可以返回。
*/
return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
}
return new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE).setFailure(t);
}
/**
* 首先获得 EventLoopGroup 对象,后调用 EventLoopGroup#register(Channel) 方法,注册 Channel 到 EventLoopGroup 中。
* 实际在方法内部,EventLoopGroup 会分配一个 EventLoop 对象,将 Channel 注册到其上。
*
* 注册 Channel 到 EventLoopGroup 中
* config().group()拿到的是boss线程调度
*
*/
ChannelFuture regFuture = config().group().register(channel);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
// 强制关闭 Channel
channel.unsafe().closeForcibly();
}
}
return regFuture;
}
io.netty.bootstrap.AbstractBootstrap#init初始化 Channel 配置
@Override
void init(Channel channel) throws Exception {
final Map, Object> options = options0();
synchronized (options) {
setChannelOptions(channel, options, logger);
}
//设置options attrs给服务端的channel对象
final Map, Object> attrs = attrs0();
synchronized (attrs) {
for (Entry, Object> e: attrs.entrySet()) {
@SuppressWarnings("unchecked")
AttributeKey
ServerBootstrapAcceptor给pipLine添加一个新连接到来的处理器,以便于服务端channel在处理accept事件的时候给客户端channel注册事件
ChannelFuture regFuture = config().group().register(channel);这个方法调用boss group来注册服务端的channel到NioEventLoop中去
io.netty.channel.MultithreadEventLoopGroup#register(io.netty.channel.Channel)
@Override
public ChannelFuture register(Channel channel) {
return next().register(channel);
}
同上篇,next回去调用线程选择器,选择一个NioEventLoop来完成注册
io.netty.channel.SingleThreadEventLoop#register(io.netty.channel.Channel)
/**
* 注册channel
* @param channel
* @return
*/
@Override
public ChannelFuture register(Channel channel) {
return register(new DefaultChannelPromise(channel, this));
}
@Override
public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
//转交给unsafe来进行注册
promise.channel().unsafe().register(this, promise);
return promise;
}
io.netty.channel.AbstractChannel.AbstractUnsafe#register
/**
* 注册channel到selector
* @param eventLoop
* @param promise
*/
@Override
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
....
//保存事件处理线程
AbstractChannel.this.eventLoop = eventLoop;
/**
* 在工作线程知己进行注册
*/
if (eventLoop.inEventLoop()) {
//注册channel
register0(promise);
} else {
try {
//否则执行task任务 添加到队列 异步进行调度
eventLoop.execute(new Runnable() {
@Override
public void run() {
register0(promise);
}
});
} catch (Throwable t) {
logger.warn(
"Force-closing a channel whose registration task was not accepted by an event loop: {}",
AbstractChannel.this, t);
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
}
eventLoop.execute(new Runnable() )此时boss线程还未启动,所以会调用eventLoop的execute方法
io.netty.util.concurrent.SingleThreadEventExecutor#execute
@Override
public void execute(Runnable task) {
if (task == null) {
throw new NullPointerException("task");
}
//判断正在执行任务的线程是否是eventloop已经保存的线程
boolean inEventLoop = inEventLoop();
addTask(task);
//如果不是在eventloop线程证明还没启动轮询和任务调度run方法
//则启动线程
if (!inEventLoop) {
//启动线程
startThread();
if (isShutdown() && removeTask(task)) {
reject();
}
}
if (!addTaskWakesUp && wakesUpForTask(task)) {
wakeup(inEventLoop);
}
}
io.netty.util.concurrent.SingleThreadEventExecutor#startThread
private void startThread() {
//状态值是未启动过
if (state == ST_NOT_STARTED) {
if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) {
try {
//真正启动的逻辑
doStartThread();
} catch (Throwable cause) {
STATE_UPDATER.set(this, ST_NOT_STARTED);
PlatformDependent.throwException(cause);
}
}
}
}
如果没启动过,那么doStartThread开始启动
private void doStartThread() {
assert thread == null;
//交给线程执行器去执行代码 ThreadPerTaskExecutor
executor.execute(new Runnable() {
@Override
public void run() {
//保存当前线程异步任务的线程
thread = Thread.currentThread();
if (interrupted) {
thread.interrupt();
}
boolean success = false;
updateLastExecutionTime();
try {
//启动NioEventLoop的run()方法 进行selector轮询
SingleThreadEventExecutor.this.run();
success = true;
} catch (Throwable t) {
使用线程执行器开启线程来执行NioEventLoop中的run方法,从而开始不断的select—>processKey—>runAllTask()
回头看io.netty.channel.AbstractChannel.AbstractUnsafe#register0
private void register0(ChannelPromise promise) {
try {
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
boolean firstRegistration = neverRegistered;
//执行注册channel的逻辑
doRegister();
neverRegistered = false;
registered = true;
//通知pipline添加操作
pipeline.invokeHandlerAddedIfNeeded();
safeSetSuccess(promise);
//通知pipline registe事件
pipeline.fireChannelRegistered();
if (isActive()) {
if (firstRegistration) {
//通知pipline的active事件 header->tail active
pipeline.fireChannelActive();
} else if (config().isAutoRead()) {
// This channel was registered before and autoRead() is set. This means we need to begin read
// again so that we process inbound data.
//
// See https://github.com/netty/netty/issues/4805
beginRead();
}
}
} catch (Throwable t) {
// Close the channel directly to avoid FD leak.
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
doRegister调用java原生的channel注册到NioEventLoop中的selector中去,不关心任何事件0,并且把channel设置给attachment,此时isActive()返回false,
初始化和注册都走完了,现在回头看io.netty.bootstrap.AbstractBootstrap#doBind0
private static void doBind0(
final ChannelFuture regFuture, final Channel channel,
final SocketAddress localAddress, final ChannelPromise promise) {
/**
* 把注册任务交给eventLoop 添加到task队列
* 在run方法里面会有处理任务的逻辑代码
*/
channel.eventLoop().execute(new Runnable() {
@Override
public void run() {
// 注册成功,绑定端口
if (regFuture.isSuccess()) {
channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} else {// 注册失败,回调通知 promise 异常
promise.setFailure(regFuture.cause());
}
}
});
}
io.netty.channel.AbstractChannel#bind(java.net.SocketAddress,io.netty.channel.ChannelPromise)
@Override
public ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
//调用pipline的bind方法
return pipeline.bind(localAddress, promise);
}
io.netty.channel.DefaultChannelPipeline#bind(java.net.SocketAddress,io.netty.channel.ChannelPromise)
@Override
public final ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise) {
//调用tail的bind方法 TailContext类
return tail.bind(localAddress, promise);
}
io.netty.channel.AbstractChannelHandlerContext#bind(java.net.SocketAddress, io.netty.channel.ChannelPromise)从tail尾部开始找
@Override
public ChannelFuture bind(final SocketAddress localAddress, final ChannelPromise promise) {
.....
//向前找找到 HeadContext
final AbstractChannelHandlerContext next = findContextOutbound();
EventExecutor executor = next.executor();
//判断是否是在eventLoop线程
if (executor.inEventLoop()) {
//执行HeadContext invokeBind
next.invokeBind(localAddress, promise);
} else {
safeExecute(executor, new Runnable() {
@Override
public void run() {
next.invokeBind(localAddress, promise);
}
}, promise, null);
}
return promise;
}
/**
* 一直往前找 找到inBound
* @return
*/
private AbstractChannelHandlerContext findContextOutbound() {
AbstractChannelHandlerContext ctx = this;
do {
ctx = ctx.prev;
} while (!ctx.outbound);
return ctx;
}
这个方法是在pipLine链表中的tail尾部向前找节点,最终找到headContext节点
io.netty.channel.DefaultChannelPipeline.HeadContext#bind
@Override
public void bind(
ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise)
throws Exception {
//调用unsafe的bind方法
unsafe.bind(localAddress, promise);
}
io.netty.channel.AbstractChannel.AbstractUnsafe#bind
@Override
public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
.....
boolean wasActive = isActive();
try {
//绑定端口操作
doBind(localAddress);
} catch (Throwable t) {
safeSetFailure(promise, t);
closeIfClosed();
return;
}
if (!wasActive && isActive()) {
//传播通知事件active
invokeLater(new Runnable() {
@Override
public void run() {
pipeline.fireChannelActive();
}
});
}
safeSetSuccess(promise);
}
doBind方法调用原生channel对象完成绑定,isActive()返回true,进行事件传播最终调用到io.netty.channel.DefaultChannelPipeline.HeadContext#channelActive
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelActive();
//注册read关心事件
readIfIsAutoRead();
}
private void readIfIsAutoRead() {
if (channel.config().isAutoRead()) {
channel.read();
}
}
在次调用到channel的read方法,调用pipline的read方法
@Override
public Channel read() {
pipeline.read();
return this;
}
最后调用到io.netty.channel.DefaultChannelPipeline.HeadContext#read
private final Unsafe unsafe;
HeadContext(DefaultChannelPipeline pipeline) {
super(pipeline, null, HEAD_NAME, false, true);
//从channel中取出unsafe
unsafe = pipeline.channel().unsafe();
setAddComplete();
}
@Override
public void read(ChannelHandlerContext ctx) {
unsafe.beginRead();
}
io.netty.channel.AbstractChannel.AbstractUnsafe#beginRead
@Override
public final void beginRead() {
assertEventLoop();
if (!isActive()) {
return;
}
try {
doBeginRead();
} catch (final Exception e) {
invokeLater(new Runnable() {
@Override
public void run() {
pipeline.fireExceptionCaught(e);
}
});
close(voidPromise());
}
}
然后开始注册感兴趣的事件
@Override
protected void doBeginRead() throws Exception {
// Channel.read() or ChannelHandlerContext.read() was called
final SelectionKey selectionKey = this.selectionKey;
if (!selectionKey.isValid()) {
return;
}
readPending = true;
//取出来构造参数传进来的ops
final int interestOps = selectionKey.interestOps();
if ((interestOps & readInterestOp) == 0) {
//注册感兴趣事件
selectionKey.interestOps(interestOps | readInterestOp);
}
}
这段代码的逻辑和上一篇客户端的注册感兴趣事件基本一样,
/**
* Create a new instance using the given {@link ServerSocketChannel}.
*/
public NioServerSocketChannel(ServerSocketChannel channel) {
super(null, channel, SelectionKey.OP_ACCEPT);
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}
到此就明了了,服务端的channel默认是对accept事件感兴趣