- 示例代码
package com.demo.study1.socket.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
public class EchoServer {
public static void main(String[] args) throws Exception {
Integer PORT = 8088;
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.DEBUG))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new EchoServerHandler());
}
});
// Start the server.
ChannelFuture f = b.bind(PORT).sync();
// Wait until the server socket is closed.
//阻塞主线程,直到网络服务被关闭
f.channel().closeFuture().sync();
} finally {
// Shut down all event loops to terminate all threads.
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
从bind方法debug进入
这里的initAndRegister是创建/初始化ServerSocketChannel对象,并注册到Seletor
这里需要看下这个init方法(初始化通道的参数,网络参数,自定义的参数等),这个方法中有下面一段代码
//ChannelInitializer是一个特殊的处理器,一般在registerd之后,执行一次,然后销毁,用于初始化channel
p.addLast(new ChannelInitializer<Channel>() {//添加处理器
@Override
public void initChannel(final Channel ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
ChannelHandler handler = config.handler();//获取配置中的handler
if (handler != null) {
pipeline.addLast(handler);
}
ch.eventLoop().execute(new Runnable() {
@Override
public void run() {
pipeline.addLast(new ServerBootstrapAcceptor(//添加新的ServerBootstrapAcceptor
ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
}
});
}
});
这里配置中的handler就是最前面示例中的LoggingHandler,添加之前只有头处理器和尾处理器
添加之后:添加多了serverbootstrap匿名实现类
进入注册方法
根据选择器,选择一个合适的NioEventLoop进行注册
断点打到register0方法,进入该方法(因为EvenLoop默认是不执行的,只有当有任务提交才会执行,所以他会以任务提交的方式执行)
这里就是在注册channel了
注册完成之后,这里在添加handler,进入方法
这里在添加最前面示例中的LoggingHandler
这里添加完LoggingHandler之后将ServerBootstrapAcceptor移除了
移除之后的只有头日志和尾三个了
传播完成注册事件
这是一个头处理器,什么都不做,只是传播事件。(就是找到下一个入站事件)
这里是传播到LoggingHandler
记录日志,继续传播事件
继续找入站事件
如果不是入站事件就一直往下找
这里找到的尾处理器了
他的实现是一个空,事件传播到此为止。register就到此结束了。