这篇文章来分析一个比较简单的handler--ChannelInitializer,这个在我们创建serverbootstrap的时候会经常用到,它用于对刚刚接收的channel进行初始化。。。
ServerBootstrap b = new ServerBootstrap(); //构建serverbootstrap对象 b.group(bossGroup, workerGroup); //设置时间循环对象,前者用来处理accept事件,后者用于处理已经建立的连接的io b.channel(NioServerSocketChannel.class); //用它来建立新accept的连接,用于构造serversocketchannel的工厂类 b.childHandler(new ChannelInitializer<SocketChannel>(){ //为accept channel的pipeline预添加的inboundhandler @Override //当新连接accept的时候,这个方法会调用 protected void initChannel(SocketChannel ch) throws Exception { // TODO Auto-generated method stub ch.pipeline().addLast(new MyChannelHandler()); //为当前的channel的pipeline添加自定义的处理函数 } }); //bind方法会创建一个serverchannel,并且会将当前的channel注册到eventloop上面, //会为其绑定本地端口,并对其进行初始化,为其的pipeline加一些默认的handler ChannelFuture f = b.bind(80).sync(); f.channel().closeFuture().sync(); //相当于在这里阻塞,直到serverchannel关闭这里我们可以说明一下它的应用场景:
(1)首先serversocketchannel中accept到socketchannel
(2)将这个用户定义的ChannelInitailizer加入到这个channel的pipeline上面去。。。这样,这个handler就可以用于处理当前这个channel上面的一些事件。。。
我们还是先来看看它的继承体系吧:
最上面的两个接口,前一篇文章已经有讲过,这个netty的handler定义中最为顶层的接口,接下来就是adapter,其实他们都是抽象类,无非是实现前面接口的方法,而且实现的很简单。。。我们首先以ChannelStateHandlerAdapter为例子来说明:
public abstract class ChannelStateHandlerAdapter extends ChannelHandlerAdapter implements ChannelStateHandler { /** * Calls {@link ChannelHandlerContext#fireChannelRegistered()} to forward * to the next {@link ChannelStateHandler} in the {@link ChannelPipeline}. * * Sub-classes may override this method to change behavior. */ @Override //调用当前的这个handler的context的fireChannelRegistered方法,相当于是会向下寻找下一个stathandler,调用其的fireChannelRegistered方法 public void channelRegistered(ChannelHandlerContext ctx) throws Exception { ctx.fireChannelRegistered(); } /** * Calls {@link ChannelHandlerContext#fireChannelUnregistered()} to forward * to the next {@link ChannelStateHandler} in the {@link ChannelPipeline}. * * Sub-classes may override this method to change behavior. */ @Override public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { ctx.fireChannelUnregistered(); } /** * Calls {@link ChannelHandlerContext#fireChannelActive()} to forward * to the next {@link ChannelStateHandler} in the {@link ChannelPipeline}. * * Sub-classes may override this method to change behavior. */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.fireChannelActive(); } /** * Calls {@link ChannelHandlerContext#fireChannelInactive()} to forward * to the next {@link ChannelStateHandler} in the {@link ChannelPipeline}. * * Sub-classes may override this method to change behavior. */ @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { ctx.fireChannelInactive(); } /** * Calls {@link ChannelHandlerContext#fireChannelReadSuspended()} to forward * to the next {@link ChannelHandler} in the {@link ChannelPipeline}. * * Sub-classes may override this method to change behavior. */ @Override public void channelReadSuspended(ChannelHandlerContext ctx) throws Exception { ctx.fireChannelReadSuspended(); } /** * Calls {@link ChannelHandlerContext#fireUserEventTriggered(Object)} to forward * to the next {@link ChannelHandler} in the {@link ChannelPipeline}. * * Sub-classes may override this method to change behavior. */ @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { ctx.fireUserEventTriggered(evt); } }它实现的方法都是直接调用当前handler的context的相应的方法,然而这些方法将会在pipeline上面从前到后寻找stathandler来处理。。。(state是从前到后,operation是从后到前、、)
至于ChannelHandlerAdapter就更简单了,直接实现空方法什么的,这里就不列出来了。。。
接下来我们来看ChannelInitializer的定义吧,它从写了channelRegistered以及inboundBufferUpdated两个方法,另外定义了一个抽象方法initChannel留给用户定义的类来实现,我们来看看channelRegistered方法的定义吧:
public final void channelRegistered(ChannelHandlerContext ctx) throws Exception { boolean removed = false; boolean success = false; try { //调用用户定义的init函数对当前的channel进行初始化 initChannel((C) ctx.channel()); ctx.pipeline().remove(this); //从当前的pipeline上面将当前的handler移除,因为没有什么用了 removed = true; ctx.fireChannelRegistered(); //激活下面的一个stathandler的channelRegistered方法,(pipeline从前到后) success = true; } catch (Throwable t) { logger.warn("Failed to initialize a channel. Closing: " + ctx.channel(), t); } finally { if (!removed) { ctx.pipeline().remove(this); } if (!success) { ctx.close(); } } }这里代码比较简单,而且注释也说的很明白了,也就是调用在用户具体定义的initChannel函数来对当前的channel进行一些初始化的操作,并且会在当前的pipeline上面将当前这个ChannelInitializer移除。。。因为没有用了。。。
这里也就告诉了我们ChannelInitializer的用法,也就是要自己定义initChannel函数,当当前的channel被注册到eventloop上面之后,会用该用户定义的函数来初始化channel,一般都是一些加入handler的操作。。。
好了这里ChannelInitializer就分析的差不多了吧。。。接下来再分析别的handler吧。。。