zoukankan      html  css  js  c++  java
  • Netty Channel组件作用

    什么是Channel?

    Channel是客户端和服务端建立的一个连接通道,是Netty抽象出来的网络I/O读写相关的接口;客户端有一个Channel(SocketChannel),服务端也有一个Channel(NioSocketChannel),当客户端和服务端建立连接后,客户端的Channel会跟服务端的Channel进行联通;

    什么是ChannelHandler?

    ChannelHandler是负责Channel的逻辑处理;

    什么是ChannelPipeline?

    ChannelPipeline负责管理ChannelHandler的容器,它的存储结构为双向链表;

    一个Channel包含一个ChannelPipeline,所有ChannelHandler都会顺序加入到ChannelPipeline中,创建Channel时会自动创建一个ChannelPipeline;每个Channel都有一个管理它的ChannelPipeline,这个关联关系是永久性的;

    io.netty.channel.AbstractChannel

    io.netty.channel.ChannelPipeline 接口都有往ChannelPipline添加ChannelHandler的addXXX方法

    而ChannelPipeline 中又维护了一个由ChannelHandlerContext 组成的双向链表,并且每个 ChannelHandlerContext 中又关联着一个 ChannelHandler;

    head为ChannelHandlerContext组成的双向链表的前驱指针,tail为ChannelHandlerContext组成的双向链表的后继指针;

    AbstractChannelHandlerContext为抽象类,最终它的实现类为io.netty.channel.DefaultChannelHandlerContext;

    io.netty.channel.DefaultChannelHandlerContext

    Channel,ChannelHandler,ChannelPipline的关系图大致如下

    Channel生命周期如下(此生命周期即每次进行网络连接都要经过的流程):

    当这些状态发生改变时,将会生成对应的事件;这些事件将会被转发给 ChannelPipeline 中的 ChannelHandler,其可以随后对它们做出响应;

    测试demo如下:

    public class EchoServerHandler extends ChannelInboundHandlerAdapter {
        private final static Logger logger = LoggerFactory.getLogger(EchoServerHandler.class);
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    
            ByteBuf data = (ByteBuf) msg;
    
            logger.info("服务端收到数据: "+ data.toString(CharsetUtil.UTF_8));
    
            ctx.writeAndFlush(data);
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    
            logger.info("EchoServerHandle channelReadComplete...");
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    
    
        /**
         * Channel已创建,但未注册到EventLoop
         * @param ctx
         * @throws Exception
         */
        @Override
        public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
            logger.info("EchoServerHandle channelRegistered...");
        }
    
        /**
         * Channel注册到EventLoop
         * @param ctx
         * @throws Exception
         */
        @Override
        public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
            logger.info("EchoServerHandle channelUnregistered...");
        }
    
        /**
         * 当客户端连接服务器完成就会触发该方法
         * @param ctx
         * @throws Exception
         */
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            logger.info("EchoServerHandle channelActive...");
        }
    
        /**
         * 客户端下线
         * @param ctx
         * @throws Exception
         */
        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            logger.info("EchoServerHandle channelInactive...");
        }
    }
    

      

    参考:《Netty实战》

  • 相关阅读:
    前端学习(六):body标签(四)
    前端学习(五):body标签(三)
    前端学习(四):body标签(二)
    前端学习(三):body标签(一)
    volatile的作用以及原理解析
    【转载】synchronized锁的升级过程
    从三个层面解析synchronized原理
    将网页图片转base64打包导出实战和踩坑
    synchronized锁住的到底是什么以及用法作用
    多线程之程序的局部性原理和伪共享问题
  • 原文地址:https://www.cnblogs.com/coder-zyc/p/14383728.html
Copyright © 2011-2022 走看看