Netty (二) Channel

Channel 概述简介

在Netty中,Channel相当于Socket的抽象,给用户提供了Socket的状态、Socket的读写等操作使用。每当建立一个连接,都创建一个连接对应的Channel 实例;

不同的连接类型,对应的Channel类型也不同

Channel类型说明
NioSocketChannel异步非阻塞的TCP客户端连接
NioServerSocketChannel异步非阻塞的TCP服务端连接
NioDatagramChannel异步非阻塞UDP连接
NioSctpChannel异步的SCTP连接
NioSctpServerChannel异步的SCTP服务端连接
Oio …同步阻塞连接
extends
extends
impl
NioSocketChannel
AbstractChannel
NioSocketServerChannel
Channel
Channel 初始化

在BootStrap初始化时,调用channel()方法传入NioSocketChannel.class,在channel()方法中创建了ReflectiveChannelFactory对象,如下:

public B channel(Class <? extends C>  channelClass){
    if(channelClass == null){
       throw new NullPointerException("channelClass");
    }
    return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
}

ReflectiveChannelFactory实现了ChannelFactory 接口,提供了唯一的方法 newChannel()方法,作用的创建Channel的工厂类。

Channel的注册
  1. AbstractBootStrap的initAndRegister()方法,触发启动Channel注册
  2. MultitheradEventLoopGroup的register()中,调用next()方法, 从内部数组中取出一个可用的EventLoop,即对应线程,跟Channel形成关联
  3. AbstractUnSafe的register0()方法中,将底层的JDK的NioSocketChannel注册至Selector上
Channel的生命周期
1
2
3
4
ChannelUnregistered
ChannelRegistered
ChannelActive
ChannelInactive
ChannelPipeLine

在创建Channel时,同时创建与其对应的ChannelPipeLine,ChannelPipeLine内部维护一个双向链表,链表的元素为ChannelHandlerContext;因此它拥有两个属性,head和tail

ChannelPipeLine的创建
(1) 在AbstractChannel的构造函数中,调用newChannelPipeLine();
(2) DefaultChannelPipeLine的构造函数中,初始化两个DefaultChannelHandlerContext的元素,分别为head和tail
(3) 在BootStrap启动时,会传入1个ChannelInitializer,在init方法中,会将这个ChannelInitializer转换为ChannelHandlerContext对象,插入ChannelPipeLine的链表中,会判断这个Handler是属于InBound还是OutBound,ChannelInitializer是一个固定为InBound的ChannelHandler

插入自定义ChannelHandler
在ChannelPipeLine创建后,它有1个head、tail、ChannelInitializer的Context,3个元素;
(1) 遍历ChannelPipeLine,找到InBound属性为True的Context,这里找到的就是ChannelInitializer的Context;
(2) 调用 context的invokeChannelRegistered方法,内部调用initChannel方法将ChannelHandler包装为ChannelContextHandler对象,插入ChannelPipeLine中;
(4) 删除ChannelPipeLine中的原来的ChannelInitializer的Context

ChannelPipeLine的事件传播机制

事件类型
Netty里事件类型分为两种,InBound事件和OutBound事件;
InBound事件是被动触发的事件,有channelRead、Active、exception等,InBound事件从Head到Tail传播;
OutBound事件是主动触发的事件,有connect、disconnct、write、flush等,OutBound时间从Tail到Head传播;
对应处理Inbound事件的就是ChannelInBoundHandler,处理OutBound事件的就是ChannelOutBoundHandler;

OutBound事件传播流程
(1) 从Tail节点开始,寻找下一个自定义的ChannelOutBoundHandler,找到则调用其对应方法,比如connect();
(2) 继续寻找下一个自定义的ChannelOutBoundHandler,找到则调用其对应方法,比如connect();
(3) 直到找到Head,Head本身即是ChannelHandlerContext也是ChannelOutBoundHandler,调用其connect()方法
(4) Head的connect方法内部调用了UnSafe的connect方法,进入底层的TCP连接动作

InBound事件传播流程
(1) 从Head节点开始,寻找下一个自定义的ChannelInBoundHandler,找到则调用其对应方法,比如channelActive();
(2) 继续寻找下一个自定义的ChannelInBoundHandler,找到则调用其对应方法,比如channelActive();
(3) 直到找到Tail,Tail本身即是ChannelHandlerContext也是ChannelInBoundHandler,调用其channelActive()方法
(4) 发现Tail的ChannelActive()方法没有任何实现,这是因为Tail的所有InBound方法都是默认不实现的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值