Channel的生命周期状态【状态转换将变为相应的事件,转发给ChannelPipeline中的ChannelHandler进行处理】
  ChannelUnregistered:Channel已经被创建,但还未注册到EventLoop
  ChannelRegistered:Channel已经被注册到了EventLoop
  ChannelActive:Channel处于活动状态(已经连接到它的远程节点)。它现在可以接收和发送数据了
  ChannelInactive:Channel没有连接到远程节点

ChannelHandler的生命周期【加入或者移除ChannelPipeline时调用这些方法,其有2个子类ChannelInboundHandler ChannelOutboundHandler】
  handlerAdded:当把ChannelHandler添加到ChannelPipeline中时被调用
  handlerRemoved:当从ChannelPipeline中移除ChannelHandler时被调用
  exceptionCaught:当处理过程中在ChannelPipeline中有错误产生时被调用

ChannelInboundHandler接口【入站】
  channelRegistered:当Channel已经注册到它的EventLoop并且能够处理I/O时被调用
  channelUnregistered:当Channel从它的EventLoop注销并且无法处理任何I/O时被调用
  channelActive:当Channel处于活动状态时被调用;Channel已经连接/绑定并且已经就绪
  channelInactive:当Channel离开活动状态并且不再连接它的远程节点时被调用
  channelReadComplete:当Channel上的一个读操作完成时被调用
  channelRead:当从Channel读取数据时被调用 【channelRead0是通过SimpleChannelInboundHandler的方法】
  ChannelWritability Changed:当Channel的可写状态发生改变时被调用。用户可以确保写操作不会完成得太快(以避免发生OutOfMemoryError)或者可以在Channel变为再次可写时恢复写入。可以通过调用Channel的isWritable()方法来检测Channel的可写性。与可写性相关的阈值可以通过Channel.config(). setWriteHighWaterMark()和    Channel.config().setWriteLowWater- Mark()方法来设置
  userEventTriggered:当ChannelnboundHandler.fireUserEventTriggered()方法被调用时被调用,因为一个POJO被传经了ChannelPipeline

ChannelOutboundHandler接口【出站 按需推迟操作或者事件(下载文件被暂停)】 channel->ChannelPipeline->ChannelOutboundHandler
  bind(ChannelHandlerContext,SocketAddress,ChannelPromise):当请求将Channel绑定到本地地址时被调用
  connect(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise):当请求将Channel连接到远程节点时被调用
  disconnect(ChannelHandlerContext,ChannelPromise):当请求将Channel从远程节点断开时被调用
  close(ChannelHandlerContext,ChannelPromise):当请求关闭Channel时被调用
  deregister(ChannelHandlerContext,ChannelPromise):当请求将Channel从它的EventLoop注销时被调用
  read(ChannelHandlerContext):当请求从Channel读取更多的数据时被调用
  flush(ChannelHandlerContext):当请求通过Channel将入队数据冲刷到远程节点时被调用
  write(ChannelHandlerContext,Object,ChannelPromise):当请求通过Channel将数据写到远程节点时被调用

资源泄漏:Netty提供了class ResourceLeakDetector 【java -Dio.netty.leakDetectionLevel=ADVANCED】

ChannelPipeline接口【每一个新创建的Channel都将会被分配一个新的ChannelPipeline】
ChannelPipeline保存了与Channel相关联的ChannelHandler;
ChannelPipeline可以根据需要,通过添加或者删除ChannelHandler来动态地修改;
ChannelPipeline有着丰富的API用以被调用,以响应入站和出站事件
ChannelHanlderContext【每加入一个Handler,就会绑定一个新建的ChannelHanlderContext】
可以通过调用ChannelHandlerContext上的pipeline()方法来获得被封闭的ChannelPipeline的引用。这使得运行时得以操作ChannelPipeline的ChannelHandler,我们可以利用这一点来实现一些复杂的设计。例如,你可以通过将ChannelHandler添加到ChannelPipeline中来实现动态的协议切换。
异常处理
ChannelHandler.exceptionCaught()的默认实现是简单地将当前异常转发给ChannelPipeline中的下一个ChannelHandler;
如果异常到达了ChannelPipeline的尾端,它将会被记录为未被处理;
要想定义自定义的处理逻辑,你需要重写exceptionCaught()方法。然后你需要决定是否需要将该异常传播出去。

每个EventLoop都由一个Thread支撑
EventLoopGroup bossGroup = new NioEventLoopGroup();//默认创建的Thread数值为Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));

  

EventLoopGroup oiobossGroup = new OioEventLoopGroup();

  

AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel>
B extends AbstractBootstarp<B,C> 子类型是父类型的一个参数类型,可以在运行时返回实例的引用以支持链式方式的调用Bootstrap 与 ServerBootstrap方法

  Bootstrap group(EventLoopGroup):设置用于处理Channel所有事件的EventLoopGroup
  Bootstrap channel(Class<? extends C>)Bootstrap channelFactory(ChannelFactory<? extends C>):channel()方法指定了Channel的实现类。如果该实现类没提供默认的构造函数[7],可以通过调用channel- Factory()方法来指定一个工厂类,它将会被bind()方法调用
<T> Bootstrap option(ChannelOption<T> option,T value):设置ChannelOption,其将被应用到每个新创建的Channel的ChannelConfig。这些选项将会通过bind()或者connect()方法设置到Channel,不管哪个先被调用。这个方法在Channel已经被创建后再调用将不会有任何的效果。支持的ChannelOption取决于使用的Channel类型。
<T> Bootstrap attr(Attribute<T> key, T value):指定新创建的Channel的属性值。这些属性值是通过bind()或者connect()方法设置到Channel的,具体取决于谁最先被调用。这个方法在Channel被创建后将不会有任何的效果。
  Bootstrap handler(ChannelHandler):设置将被添加到ChannelPipeline以接收事件通知的ChannelHandler
  Bootstrap clone():创建一个当前Bootstrap的克隆,其具有和原始的Bootstrap相同的设置信息
  Bootstrap remoteAddress(SocketAddress):设置远程地址。或者,也可以通过connect()方法来指定它
  ChannelFuture connect():连接到远程节点并返回一个ChannelFuture,其将会在连接操作完成后接收到通知
  ChannelFuture bind():绑定Channel并返回一个ChannelFuture,其将会在绑定操作完成后接收到通知,在那之后必须调用Channel. connect()方法来建立连接

EventLoopGroup bossGroup = new NioEventLoopGroup();//处理channel所有事件的group
ServerBootstrap serverBootstrap = new ServerBootstrap();//创建和连接新的服务端channel
serverBootstrap.group(bossGroup, workerGroup)//提供处理新链接channel事件的事件组
.channel(NioServerSocketChannel.class)//指定所用的channel
.childHandler(new ChannelInitializer<SocketChannel>() {//设置处理channel事件和数据的handler
@Override
public void initChannel(SocketChannel ch) throws Exception {

  

ServerBootstrap bootstrap = new ServerBootstrap();  // ← --  创建ServerBootstrap 以创建ServerSocketChannel,并绑定它
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())// ← -- 设置EventLoopGroup,其将提供用以处理Channel 事件的EventLoop
.channel(NioServerSocketChannel.class)// ← -- 指定要使用的Channel 实现
.childHandler(// ← -- 设置用于处理已被接受的子Channel 的I/O 和数据的ChannelInboundHandler
new SimpleChannelInboundHandler<ByteBuf>() {
ChannelFuture connectFuture;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Bootstrap bootstrap = new Bootstrap();// ← -- 创建一个Bootstrap类的实例以连接到远程主机
bootstrap.channel(NioSocketChannel.class).handler(// ← -- 指定Channel的实现
new SimpleChannelInboundHandler<ByteBuf>() { // ← -- 为入站I/O 设置ChannelInboundHandler
@Override
protected void channelRead0(
ChannelHandlerContext ctx, ByteBuf in)
throws Exception {
System.out.println("Received data");
}
});
bootstrap.group(ctx.channel().eventLoop());// ← -- 使用与分配给已被接受的子Channel 相同的EventLoop
connectFuture = bootstrap.connect(
new InetSocketAddress("www.123.com", 80)); // ← -- 连接到远程节点
} @Override
protected void channelRead0(
ChannelHandlerContext channelHandlerContext,
ByteBuf byteBuf) throws Exception {
if (connectFuture.isDone()) {//当连接完成时,执行一些数据操作(如代理)
}
}
});
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));// ← -- 通过配置好的ServerBootstrap绑定该Server-SocketChannel
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Server bound");
} else {
System.err.println("Bind attempt failed");
channelFuture.cause().printStackTrace();
}
}
});

  

Netty引导流程解读的更多相关文章

  1. linux引导流程

    本章重点: 1.linux引导流程 2.linux运行级别 3.linux启动服务管理 4.GRUB配置与应用 5.启动故障分析解决 linux启动流程 1.固件(fireware):固话在硬件上的程 ...

  2. (五)Linux引导流程解析

    目录 Linux引导流程 Linux运行级别 Linux启动服务管理 GRUB配置与应用 启动故障分析与解决 Linux引导流程 Linux系统引导流程如下图: 固件(Firmware)就是写入ERO ...

  3. 9.Linux系统引导流程

    一.Linux系统引导流程 当我们按下主机电源键的那时候开始,主板上的CMOS/BIOS模块将进行固件自检,以此检查各个硬件是否正确连接. 在Linux引导流程中,一般可以分为以下几个主要过程: 1. ...

  4. 平述factory reset ——从main system到重引导流程

    关于Android或linux的引导流程,网上大都是从开机开始讲述的,或者直接跳过bootloader引导阶段,直接从init进程开始说起.这里我从手机正常运行状态开始,到重启状态以及重启之后的状态略 ...

  5. Linux引导流程(第二版)

    Linux引导流程 柱面,0磁头,1扇区 如图:] 进入这一步骤的目的是[通常,PID是随机分配的,但是init特殊,可以通过命令:ps -el | more 查看],Linux系统中init名义上可 ...

  6. 5linux引导流程解析

    课程大纲  Linux引导流程  Linux运行级别  Linux启动服务管理  GRUB配置与应用  启动故障分析与解决     常用固件设置 安全设置 可引导介质列表 可引导介质搜索顺序 ...

  7. linux 启动引导流程

    课程大纲: Linux引导流程 Linux运行级别 Linux启动服务管理 GRUB配置与应用 启动故障分析与解决 系统引导流程 1.固件firmware(CMOS(固化在硬件上的程序与硬件统称)/B ...

  8. Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化

    Netty源码分析第一章:Netty启动流程   第三节:服务端channel初始化 回顾上一小节的initAndRegister()方法: final ChannelFuture initAndRe ...

  9. Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用

    Netty源码分析第一章:Netty启动流程   第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继 ...

随机推荐

  1. vue刷新本页面

    顶层app.vue页面 <template> <div id="app"> <router-view v-if="isRouterAlive ...

  2. SQL With As 用法Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介

    Sql 四大排名函数(ROW_NUMBER.RANK.DENSE_RANK.NTILE)简介   排名函数是Sql Server2005新增的功能,下面简单介绍一下他们各自的用法和区别.我们新建一张O ...

  3. case....when ...多重判断

    CASE...WHEN 进行多重判断 CASE WHEN A  IS NOT NULL THEN B WHEN C IS NULL THEN CASE WHEN D IS NOT NULL THEN ...

  4. Python - 面对对象(进阶)

    目录 Python - 面对对象(进阶) 类的成员 一. 字段 二. 方法 三. 属性 类的修饰符 类的特殊成员 Python - 面对对象(进阶) 类的成员 一. 字段 字段包括:普通字段和静态字段 ...

  5. JavaSE 学习笔记之StringBuffer(十五)

    --< java.lang >-- StringBuffer字符串缓冲区: 构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符. 特点: 1:可以对字符串内容进行修改. 2:是一 ...

  6. ansible special topics

    1.加速模式运行playbook accelerate 对于使用ansible 1.5 及之后版本的用户,加速模式只在以下情况下有用处: (A) 管理红帽企业版 Linux 6 或者更早的那些依然使用 ...

  7. 允许MS SqlServer远程连接

    实际问题: 服务器192.168.0.103上的SQL Express数据库实例,局域网内其余机器的Sql Server Management Studio都无法连接. 在本机上,可以用“.\SqlE ...

  8. Jquery书写ajax

    根据API学习本章 Jquery书写ajax 使用ajax发送表单到servlet,发送时显示等待图片,servlet处理完返回信息,在页面显示返回信息,并且隐藏等待图片 <%@ page la ...

  9. L - 贪心 基础

    Once upon a time, in the Kingdom of Loowater, a minor nuisance turned into a major problem. The shor ...

  10. java Regex

    超全 http://www.rexegg.com/regex-lookarounds.html 这篇文章不错:http://www.cnblogs.com/lzq198754/p/5780340.ht ...