Netty学习四:Channel
1. Channel
Channel是Netty的核心概念之一,它是Netty网络通信的主体,由它负责同对端进行网络通信、注册和数据操作等功能。
1.1 工作原理

如上图所示:
- 一旦用户端连接成功,将新建一个channel同该用户端进行绑定
- channel从EventLoopGroup获得一个EventLoop,并注册到该EventLoop,channel生命周期内都和该EventLoop在一起(注册时获得selectionKey)
- channel同用户端进行网络连接、关闭和读写,生成相对应的event(改变selectinKey信息),触发eventloop调度线程进行执行
- 如果是读事件,执行线程调度pipeline来处理用户业务逻辑
1.2 状态转换

如上图所示,Channel包含注册、活跃、非活跃和非注册状态,在一般情况下是从注册->活跃->非活跃->非注册,但用户可以从eventloop取消和重注册channel,因此在此情况下活跃->非注册->注册
1.3 线程
多个channel可以注册到一个eventloop上,所有的操作都是顺序执行的,eventloop会依据channel的事件调用channel的方法进行相关操作,每个channel的操作和处理在eventloop中都是顺序的,如下图:

2. ChannelPipeline和ChannelHandler
ChannelPipeline和ChannelHandler用于channel事件的拦截和处理,Netty使用类似责任链的模式来设计ChannelPipeline和ChannelHandler
ChannelPipeline相当于ChannelHandler的容器,channel事件消息在ChannelPipeline中流动和传播,相应的事件能够被ChannelHandler拦截处理、传递、忽略或者终止,如下图所示:

2.1 INBOUD和OUTBOUND事件
inbound:当发生某个I/O操作时由IO线程流向用户业务处理线程的事件,如链路建立、链路关闭或者读完成等
outbound:由用户线程或者代码发起的IO操作事件
2.2 ChannelHandlerContext
每个ChannelHandler 被添加到ChannelPipeline 后,都会创建一个ChannelHandlerContext 并与之创建的ChannelHandler 关联绑定。如下图:

ChannelHandler通过ChannelHandlerContext来操作channel和channelpipeline
2.3 ChannelHandler
ChannelHandler负责I/O事件或者I/O操作进行拦截和处理,用户可以通过ChannelHandlerAdapter来选择性的实现自己感兴趣的事件拦截和处理。
由于Channel只负责实际的I/O操作,因此数据的编解码和实际处理都需要通过ChannelHandler进行处理。
2.4 注意
ChannelPipeline是线程安全的,多个业务线程可以并发的操作ChannelPipeline;ChannelHandler不是线程安全的,用户需要自己保重ChannelHandler的线程安全
3. ChannelFuture与ChannelPromise
在Netty中,所有的I/O操作都是异步的,因此调用一个I/O操作后,将继续当前线程的执行,但I/O操作的结果怎么获得?——ChannelFuture。

如上图,当前线程A异步发起I/O操作后,不阻塞继续执行相关操作,当IO线程B完成后,通过回调执行A设置的回调方法。
回调方法通过监听的形式实现:ChannelFutureListener。
ChannelPromise是ChannelFuture的扩展,允许设置I/O操作的结果,使ChannelFutureListener可以执行相关操作
Netty学习四:Channel的更多相关文章
- Netty学习(四)-TCP粘包和拆包
我们都知道TCP是基于字节流的传输协议.那么数据在通信层传播其实就像河水一样并没有明显的分界线,而数据具体表示什么意思什么地方有句号什么地方有分号这个对于TCP底层来说并不清楚.应用层向TCP层发送用 ...
- Netty学习(四)FastThreadLocal
FastThreadLocal 前面介绍过 JDK 的 ThreadLocal , 使用不当的话容易造成内存泄漏最终导致OOM, 并且也有一些地方设计的不够好(相对于接下来要介绍的 FastThrea ...
- Netty 学习(四):ChannelHandler 的事件传播和生命周期
Netty 学习(四):ChannelHandler 的事件传播和生命周期 作者: Grey 原文地址: 博客园:Netty 学习(四):ChannelHandler 的事件传播和生命周期 CSDN: ...
- Netty学习之客户端创建
一.客户端开发时序图 图片来源:Netty权威指南(第2版) 二.Netty客户端开发步骤 使用Netty进行客户端开发主要有以下几个步骤: 1.用户线程创建Bootstrap Bootstrap b ...
- Netty 学习笔记(1)通信原理
前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始. Netty 的通信原理 Netty 底层 ...
- Netty学习笔记(二)——netty组件及其用法
1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...
- Netty 学习(二):服务端与客户端通信
Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...
- Netty 学习(十):ChannelPipeline源码说明
Netty 学习(十):ChannelPipeline源码说明 作者: Grey 原文地址: 博客园:Netty 学习(十):ChannelPipeline源码说明 CSDN:Netty 学习(十): ...
- Netty 学习 一、初识Netty【原创】
在过去几年的工作和学习中,比较关注高层次的应用开发,对底层探究较少.实现Web应用的开发,主要依赖Tomcat.Apache等应用服务器,程序员无需了解底层协议,但同样限制了应用的性能和效率.现在开始 ...
随机推荐
- Build Android Webrtc Libjingle Library On Ubuntu
Our team is developing an app to help people solve problem face to face. We choose webrtc protocol a ...
- 字符串流stringstream(头文件sstream)
今天看到一样很有趣的东西,可以用于各种类型的转换.其实一个文本可以看作一个长长的字符串,整数啊浮点数的都是字符串,于是在字符串流里面就可以很方便地玩转各种类型,比如说: #include<ios ...
- Delphi 版 MIB_IF_ROW2
unit netioapi; interface uses Windows; type {$Z4} NDIS_MEDIUM = ( NdisMedium802_3, NdisMedium802_5, ...
- 百度音乐api
百度音乐全接口 会利用使用接口找歌简单又快捷 http://tingapi.ting.baidu.com/v1/restserver/ting 获取方式:GET 参数:format=json或xml& ...
- C++中的注解理解
SAL: the Microsoft Source Code Annotation Language. SAL: the Microsoft Source Code Annotation Langua ...
- HTTP方法:GET对比POST
http://blog.csdn.net/zhenyu5211314/article/details/17067817
- stanford-parser使用说明
主意:本说明文档针对stanford-parser-full-2014-06-16.不同版本的parser,其功能和表示形式可能会略有不同.但总体不会有太大差异 Stanford parser是一款较 ...
- Courier-MTA 0.72 发布,电子邮件系统
Courier-MTA 0.72 增加了 ratefilter,用来限制速率的邮件过滤器. Courier 是一个优秀的电子信件系统,功能上它远比 Qmail. Postfix 等我们已经熟知的系统完 ...
- Python札记 -- MongoDB模糊查询
最近在使用MongoDB的时候,遇到了使用多个关键词进行模糊查询的场景.竹风使用的是mongoengine库. 查了各种资料,最后总结出比较好用的方法.先上代码,后面进行详细说明.如下: #!/usr ...
- 使用call来实现继承
function Class1(arg1,arg2) { this.name = arg1; this.pass = arg2; this.showSub = function() { return ...