工作中可能经常会碰到Netty相关程序的处理,但是很多时候都是知其然不知其所以然,阅读其源码是一个很好的方式加深自己对程序的理解,而且Netty本身也是一个非常优秀的异步编程框架,读大师的代码,是很好的成长方式
先从Netty服务端启动的程序开始看:
服务端Netty代码
一般服务端代码如下:
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
// 服务端的BootStrap,一个需要接受连接,一个用来处理事件
b.group(bossGroup, workerGroup)
// Channel理解为通道,网络传输的通道类型
.channel(NioServerSocketChannel.class)
// ChannerlHandler要被装进ChannelPipeline
// 而过程则是调用ChannelInitializer的iniChannel方法
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws Exception {
// addLast,在PipeLine中的Handler是有顺序的,所以
// 有addLast,addFirst等方法
// 添加的同时,可以指定Encoder和Decoder
ch.pipeline().addLast(new RequestDecoder(),
new ResponseDataEncoder(),
new ProcessingHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
分析
- Channel的创建
ServerBootStrap.bind -> doBind(SocketAddress) -> initAndRegister() ->
channel = channelFactory.newChannel();
在ServerBootStrap中的initAndRegister方法里,channel是通过ChannelFactory进行创建的。
- ChannelFactory的设置,既然Channel通过ChannelFactory创建的,那么ChannelFactory是在哪里设置的呢?
点击ChannelFactory可以看到如下使用ChannelFactory的地方,在116行的地方有。
image.png
另外在我们的程序之中,只有channel方法设置了Channel:然后往下看
ServerBootStrap.channel(Class<? extends C> channelClass)
-> channelFactory(new ReflectiveChannelFactory<C>(channelClass))
-> channelFactory(ChannelFactory<? extends C> channelFactory)
-> this.channelFactory = channelFactory;
- Channel的初始化操作,创建Channel之后我们可以看到在ServerBootStrap中对其调用init(channel)方法。
- 在init方法处理Channel之前,我们看一下Channel的构造方法,因为我们传的是NioServerSocketChannel.class,看一下它的构造方法
这不是NIO编程常看到的:
DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider()
-> newSocket(SelectorProvider provider)
->provider.openServerSocketChannel()
->
image.png
->
image.png
最终在NioServerSocketChannel中:
- ch: provider.openServerSocketChannel()
- readInterestoP: SelectionKey.OP_ACCEPT
- id:DefaultChannelId.newInstance()
- unSafe: new NioMessageUnsafe()
- pipeLine: new DefaultChannelPipeline(this)
- config: new NioServerSocketChannelConfig(this, javaChannel().socket())
到这里是完成了channel的构造工作。
-
另外看一下ServerBootStrap的config属性。
image.png
最后
这里先看ServerBootStrap的channel创建与构建的处理,后面再进行服务端启动的其它选项配置。
网友评论