不管是服务端还是客户端 Netty都是先准备原材料 真正用到的时候才开辟资源
1 准备哪些原材料
- parent group
- child group
- channel factory
- parent handler
- child handler
- options
1 2 3 4 5 6 7 8 9 10 11 12 13
| ServerBootstrap b = new ServerBootstrap(); b .group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 100) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new EchoServerHandler()); } });
|
2 bind触发资源开辟
Netty-05-Channel
3 配置channel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
@Override void init(Channel channel) { setChannelOptions(channel, newOptionsArray(), logger); setAttributes(channel, newAttributesArray());
ChannelPipeline p = channel.pipeline();
final EventLoopGroup currentChildGroup = childGroup; final ChannelHandler currentChildHandler = childHandler; final Entry<ChannelOption<?>, Object>[] currentChildOptions = newOptionsArray(childOptions); final Entry<AttributeKey<?>, Object>[] currentChildAttrs = newAttributesArray(childAttrs);
p.addLast(new ChannelInitializer<Channel>() { @Override public void initChannel(final Channel ch) { final ChannelPipeline pipeline = ch.pipeline(); ChannelHandler handler = config.handler(); if (handler != null) pipeline.addLast(handler);
ch.eventLoop().execute(new Runnable() { @Override public void run() { pipeline.addLast( new ServerBootstrapAcceptor( ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs ) ); } }); } }); }
|
并且这个方法什么时候被回调呢,在channel注册到selector后会发布事件触发
1 2 3 4 5 6
|
pipeline.invokeHandlerAddedIfNeeded();
|
4 启动了EventLoop线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
ChannelFuture regFuture = this .config() .group() .register(channel);
|
服务端彻底启动
- socket完成了bind
- socket完成了listen
- 注册IO多路复用器关注连接事件
- IO线程阻塞在复用器上等待客户端的连接进来
Netty-13-接收客户端连接