目录
一.重要类
1.NioEventLoopGroup、NioEventLoop
相当于线程池和线程。NioEventLoop中可以执行Channel相关的非阻塞io操作和已提交的Runnable任务,这两种任务执行的时间比例可以通过ioRatio设置,默认50。
2.Channel
常用的有NioServerSocketChannel和NioSocketChannel,是对java原生的ServerSocketChannel和SocketChannel进行了包装,其中聚合了unsafe、pipline等对象。
3.Unsafe
底层工作者,执行实际的I/O操作。
4.ChannelPipeline
持有ChannelHandlerContext(ChannelHandler)的链表,ChannelHandler链表会根据Handler的类型,分为InBound和OutBound两条执行链路。ChannelPipeline是执行相应in、out事件的门面。
5.ChannelHandlerContext
对ChannelHandler进行包装,持有Unsafe和ChannelPipeline的引用。ChannelHandler的in、out方法参数中包含了当前ChannelHandlerContext的引用。ChannelHandlerContext的in、out方法逻辑都是执行当前链路下一个handler对应的方法,这是责任链模式的一种实现。
二.启动、工作流程
1.服务端
1)ServerBootstrap.bind() 中执行initAndRegister(),初始化NioServerSocketChannel(构造函数中会设置readInterestOp为SelectionKey.OP_ACCEPT),注册NioServerSocketChannel到bossGroup的一个eventLoop上。在eventLoop中执行pipeline.bind(),通过headContext.bind()调用java原生ServerSocketChannel.bind()开启端口监听。一个端口只会占用bossGroup的一个eventLoop进行监听,因此,如果只监听一个端口,bossGroup线程数设置为1即可。
2)bossGroup的eventLoop会调用selector.select(long time)处理NioServerSocketChannel的ACCEPT事件,当事件就绪后,会通过NioServerSocketChannel的unsafe执行java原生ServerSocketChannel.accept(),得到SocketChannel,并封装成NioSocketChannel(构造函数中会设置readInterestOp为SelectionKey.OP_READ),缓存到buf中。
3)随后执行NioServerSocketChannel中pipeline.fireChannelRead(),会调用in事件处理链路上的ServerBootstrapAcceptor.channelRead(),将上一步构造的NioSocketChannel注册到workerGroup的一个eventLoop上。
4)workerGroup的eventLoop会调用selector.select(long time)处理NioSocketChannel的io事件,由于构造时已经注册了SelectionKey.OP_READ,因此会先轮询读事件,事件触发后会执行NioSocketChannel中pipeline.fireChannelRead()。
2.客户端
1)Bootstrap.connect() 中执行initAndRegister(),初始化NioSocketChannel(构造函数中会设置readInterestOp为SelectionKey.OP_READ),注册NioServerSocketChannel到workerGroup的一个eventLoop上。在eventLoop中执行pipeline.connect(),通过headContext.connect()调用java原生ServerSocketChannel.connnect()进行连接。
2)同服务端的4)