netty的启动过程是咋样的,就是那里启动了socket监听,咋处理请求的( 二 )
我们不难发现基于Java Nio创建一个Server,主要分为以下几步:
创建一个ServerSocketChannel设置io模型,阻塞或者非阻塞 serverChannel.configureBlocking(false);创建selector多路复用器,注册监听OP_ACCEPT事件那么,我们那跟踪以下netty究竟是在哪做的这些封装,接下来我们将示例如何debug代码,追踪echoServer的启动调用过程。
首先我们看netty EchoServer中bootstrap.bind(new InetSocketAddress(port))方法,跟进来,我们看到它调用了如下方法: public Channel bind(final SocketAddress localAddress) { //异步绑定,返回一个ChannelFuture ChannelFuture future = bindAsync(localAddress); // Wait for the future. future.awaitUninterruptibly(); if (!future.isSuccess()) { future.getChannel().close().awaitUninterruptibly(); throw new ChannelException("Failed to bind to: " + localAddress, future.getCause()); } return future.getChannel(); }我们继续跟进去bindAsync方法: public ChannelFuture bindAsync(final SocketAddress localAddress) { if (localAddress == null) { throw new NullPointerException("localAddress"); } Binder binder = new Binder(localAddress); ChannelHandler parentHandler = getParentHandler(); ChannelPipeline bossPipeline = pipeline(); bossPipeline.addLast("binder", binder); if (parentHandler != null) { bossPipeline.addLast("userHandler", parentHandler); } // getFactory()方法返回的就是我们在初始化ServerBootstrap传入的NioServerSocketChannelFactory Channel channel = getFactory().newChannel(bossPipeline); final ChannelFuture bfuture = new DefaultChannelFuture(channel, false); binder.bindFuture.addListener(new ChannelFutureListener() { public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { bfuture.setSuccess(); } else { // Call close on bind failure bfuture.getChannel().close(); bfuture.setFailure(future.getCause()); } } }); return bfuture; }在bindAsync方法中,我们通过Channel channel = getFactory().newChannel(bossPipeline);获取了一个channel。在初始化Serverbootstrap的时候我们传入了NioServerSocketChannelFactory,NioServerSocketChannelFactory是创建NioServerSocketChannel的工厂方法,所以这里我们获取的channel的实现是NioServerSocketChannel。下面,我们要看NioServerSocketChannel里面做了些什么?我们来看NioServerSocketChannel的构造方法: NioServerSocketChannel( ChannelFactory factory, ChannelPipeline pipeline, ChannelSink sink, Boss boss, WorkerPool\u0026lt;NioWorker\u0026gt; workerPool) { super(factory, pipeline, sink); // boss 是早期版本netty用来处理accept连接的线程,仅仅使用了单线程,后来的版本中用了EventLoop,而且也改成了线程池的模型,也就是EventLoopGroup this.boss = boss; // workerPool就是netty用来处理io的线程池, this.workerPool = workerPool; try { // 创建了ServerSocketChannel socket = ServerSocketChannel.open(); } catch (IOException e) { throw new ChannelException( "Failed to open a server socket.", e); } try { // 设置为非阻塞模型 socket.configureBlocking(false); } catch (IOException e) { try { socket.close(); } catch (IOException e2) { if (logger.isWarnEnabled()) { logger.warn( "Failed to close a partially initialized socket.", e2); } } throw new ChannelException("Failed to enter non-blocking mode.", e); } // config = new DefaultServerSocketChannelConfig(socket.socket()); //调用Channels.fireChannelOpen(this) fireChannelOpen(this); }
推荐阅读
- 强寒潮来袭浙江启动低温雨雪冰冻灾害Ⅳ级应急响应
- 西藏航空一机长执飞过程中身体不适降落后送医去世
- 江苏省13市启动重污染天气黄色预警
- 兰州启动进口冷链食品监管总仓“出仓”须查验证明
- 朋友圈直播酒驾全过程?警方:当事人涉嫌酒驾接受调查
- “艺术无障碍平台”正式启动
- |共促和谐劳动关系 工会法律和集体协商技能竞赛启动
- 正点财经|
- |苏州·中国声学创新谷在常熟启动
- 大三学生准备日本留学过程中要不要准备考研
