Netty整理(二) 顶

  • 2019 年 10 月 10 日
  • 筆記

Netty整理

现在我们来验证一下channel的生命周期。

我们将EchoServerHandler修改如下,增加全部的监听事件,并打印事件方法名称。

/**   * 事件处理器   */  @Slf4j  public class EchoServerHandler extends ChannelInboundHandlerAdapter {      /**       * 监听读取事件       * @param ctx       * @param msg       * @throws Exception       */      @Override      public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {          ByteBuf data = (ByteBuf) msg;          log.info(data.toString(CharsetUtil.UTF_8));          ctx.writeAndFlush(data);      }        /**       * 监听读取完毕事件       * @param ctx       * @throws Exception       */      @Override      public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {          log.info("channelReadComplete");      }        /**       * 监听异常事件       * @param ctx       * @param cause       * @throws Exception       */      @Override      public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {          cause.printStackTrace();          ctx.close();      }        /**       * 将channel注册到EventLoop的Selector多路复用器中       * @param ctx       * @throws Exception       */      @Override      public void channelRegistered(ChannelHandlerContext ctx) throws Exception {          log.info("channelRegistered");      }        /**       * channel未注册到EventLoop中       * @param ctx       * @throws Exception       */      @Override      public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {          log.info("channelUnregistered");      }        /**       * 有连接,变为活跃状态       * @param ctx       * @throws Exception       */      @Override      public void channelActive(ChannelHandlerContext ctx) throws Exception {          log.info("channelActive");      }        /**       * 没有连接,非活跃状态       * @param ctx       * @throws Exception       */      @Override      public void channelInactive(ChannelHandlerContext ctx) throws Exception {          log.info("channelInactive");      }  }

启动EchoServer,打开telnet连接到端口,我们可以看到

admindeMacBook-Pro:~ admin$ telnet 127.0.0.1 10101 Trying 127.0.0.1… Connected to localhost. Escape character is '^]'. sdfs sdfs ^] telnet> quit Connection closed.

整个过程为连接,发送字符串sdfs,退出连接

服务端日志为

2019-10-01 05:33:36.960 INFO 543 — [ntLoopGroup-3-1] c.g.websocket.netty.EchoServerHandler : channelRegistered 2019-10-01 05:33:36.960 INFO 543 — [ntLoopGroup-3-1] c.g.websocket.netty.EchoServerHandler : channelActive 2019-10-01 05:33:54.439 INFO 543 — [ntLoopGroup-3-1] c.g.websocket.netty.EchoServerHandler : sdfs

2019-10-01 05:33:54.442 INFO 543 — [ntLoopGroup-3-1] c.g.websocket.netty.EchoServerHandler : channelReadComplete 2019-10-01 05:34:22.527 INFO 543 — [ntLoopGroup-3-1] c.g.websocket.netty.EchoServerHandler : channelReadComplete 2019-10-01 05:34:22.529 INFO 543 — [ntLoopGroup-3-1] c.g.websocket.netty.EchoServerHandler : channelInactive 2019-10-01 05:34:22.529 INFO 543 — [ntLoopGroup-3-1] c.g.websocket.netty.EchoServerHandler : channelUnregistered

整个生命周期正如前面写到一样

Channel的生命周期为:(1)channelRegistered->(3)channelActive->(4)channelInactive->(2)channelUnregistered

ChannelPipeline: 好比厂里的流水线一样,可以在上面添加多个ChannelHanler,也可看成是一串 ChannelHandler 实例,拦截穿过 Channel 的输入输出 event, ChannelPipeline 实现了拦截器的一种高级形式,使得用户可以对事件的处理以及ChannelHanler之间交互获得完全的控制权。

我们来看一下ChannelPipeline的源码

public interface ChannelPipeline          extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Entry<String, ChannelHandler>> {        /**       * 在管道的首位置添加一个channelhandler       */      ChannelPipeline addFirst(String name, ChannelHandler handler);        /**       * 同上,多了一个线程池参数       */      ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);        /**       * 在管道的最末端添加一个channelhandler       */      ChannelPipeline addLast(String name, ChannelHandler handler);        /**       * 同上,多了一个线程池参数       */      ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);        /**       * 在一个管道中已存在的channelhandler之前插入另外一个channelhandler       */      ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);        /**       * 同上,多了一个线程池参数       */      ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);        /**       * 在管道已有多一个channelhandler之后插入另外一个channelhandler       */      ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);        /**       * 同上,多了一个线程池参数       */      ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);        /**       * 在该管道的首位置放入一组channelhandler       *       */      ChannelPipeline addFirst(ChannelHandler... handlers);        /**       * 同上,多了一个线程池参数       *       */      ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);        /**       * 在管道的最末端放入一组channelhandler       *       */      ChannelPipeline addLast(ChannelHandler... handlers);        /**       * 同上,多了一个线程池参数       *       */      ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);        /**       * 从管道中移除一个channelhandler       */      ChannelPipeline remove(ChannelHandler handler);        /**       * 根据名字在管道中移除一个channelhandler       */      ChannelHandler remove(String name);        /**       * 根据类名在管道中移除一个channelhandler       */      <T extends ChannelHandler> T remove(Class<T> handlerType);        /**       * 移除管道中首个channelhandler       */      ChannelHandler removeFirst();        /**       * 移除管道中末个channelhandler       */      ChannelHandler removeLast();        /**       * 在管道中用新的channelhandler替换旧的channelhandler,中间参数都是替换者的名字       */      ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);        /**       * 在管道中用新的channelhandler替换旧的channelhandler,中间参数都是替换者的名字       */      ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);        /**       * 在管道中用新的channelhandler替换旧的channelhandler,中间参数都是替换者的名字       */      <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,                                           ChannelHandler newHandler);        /**       * 返回管道中首个channelhandler       */      ChannelHandler first();        /**       * 获取第一个管道处理器上下文       */      ChannelHandlerContext firstContext();        /**       * 获取管道中最后一个channelhandler       */      ChannelHandler last();        /**       * 获取管道中最后一个管道处理器上下文       */      ChannelHandlerContext lastContext();        /**       * 根据名字获取管道中的一个channelhandler       */      ChannelHandler get(String name);        /**       * 根据类获取一个channelhandler       */      <T extends ChannelHandler> T get(Class<T> handlerType);        /**       * 根据channelhandler获取一个管道处理器上下文       */      ChannelHandlerContext context(ChannelHandler handler);        /**       * 根据名字获取一个管道处理器上下文       */      ChannelHandlerContext context(String name);        /**       * 根据一个channelhandler的类名获取一个管道处理器上下文       */      ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);        /**       * 返回一个管道       */      Channel channel();        /**       * 返回管道中的channelhandler的名称列表       */      List<String> names();        /**       * Converts this pipeline into an ordered {@link Map} whose keys are       * handler names and whose values are handlers.       */      Map<String, ChannelHandler> toMap();        @Override      ChannelPipeline fireChannelRegistered();         @Override      ChannelPipeline fireChannelUnregistered();        @Override      ChannelPipeline fireChannelActive();        @Override      ChannelPipeline fireChannelInactive();        @Override      ChannelPipeline fireExceptionCaught(Throwable cause);        @Override      ChannelPipeline fireUserEventTriggered(Object event);        @Override      ChannelPipeline fireChannelRead(Object msg);        @Override      ChannelPipeline fireChannelReadComplete();        @Override      ChannelPipeline fireChannelWritabilityChanged();        @Override      ChannelPipeline flush();  }