Netty Channel模块作用

什么是Channel?

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

Netty Channel模块作用

 

什么是ChannelHandler?

ChannelHandler是负责Channel的逻辑处理;

 

什么是ChannelPipeline?

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

 

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

Netty Channel模块作用

 

io.netty.channel.AbstractChannel

Netty Channel模块作用

 

Netty Channel模块作用

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

 

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

Netty Channel模块作用

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

 

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

Netty Channel模块作用

 

io.netty.channel.DefaultChannelHandlerContext

Netty Channel模块作用

 

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

Netty Channel模块作用

 

 

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

Netty Channel模块作用

 

 

Netty Channel模块作用

 

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

 

测试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 Channel模块作用

 

参考:《Netty实战》

Netty Channel模块作用

上一篇:js 函数高级


下一篇:js 基础总结