Netty In Action中文版 - 第三章:Netty核心概念
在这一章我们将讨论Netty的10个核心类。清楚了解他们的结构对使用Netty非常实用。可能有一些不会再工作中用到。可是也有一些非经常常使用也非常核心,你会遇到。
- Bootstrap or ServerBootstrap
- EventLoop
- EventLoopGroup
- ChannelPipeline
- Channel
- Future or ChannelFuture
- ChannelInitializer
- ChannelHandler
本节的目的就是介绍以上这些概念。帮助你了解它们的使用方法。
3.1 Netty Crash Course
事件能够描写叙述成一个非常通用的方法,由于你能够自己定义一个handler,用来将Object转成byte[]或将byte[]转成Object;也能够定义个handler处理抛出的异常。
能够觉得应用程序的业务逻辑都是在ChannelInboundHandler中来处理的。业务罗的生命周期在ChannelInboundHandler中。
ChannelPipeline和EventLoop和EventLoopGroup密切相关,由于它们三个都和事件处理相关。所以这就是为什么它们处理IO的工作由EventLoop管理的原因。
3.2 Channels,Events and Input/Output(IO)
这样的方式不好,由于同步会影响程序的性能,Netty的设计保证程序处理事件不会有同步。
3.3 什么是Bootstrap?为什么使用它?
- Bootstrap用来连接远程主机,有1个EventLoopGroup
- ServerBootstrap用来绑定本地port,有2个EventLoopGroup
事件组(Groups)。传输(transports)和处理程序(handlers)分别在本章后面讲述,我们在这里仅仅讨论两种"引导"的差异(Bootstrap和ServerBootstrap)。第一个差异非常明显,“ServerBootstrap”监听在server监听一个port轮询client的“Bootstrap”或DatagramChannel是否连接server。通常须要调用“Bootstrap”类的connect()方法。可是也能够先调用bind()再调用connect()进行连接,之后使用的Channel包括在bind()返回的ChannelFuture中。
一个ServerBootstrap能够觉得有2个channels组。第一组包括一个单例ServerChannel,代表持有一个绑定了本地port的socket。第二组包括全部的Channel。代表server已接受了的连接。
下图形象的描写叙述了这样的情况:
3.4 Channel Handlers and Data Flow(通道处理和数据流)
Handlers自身依赖于ChannelPipeline来决定它们运行的顺序,因此不可能通过ChannelPipeline定义处理程序的某些方面,反过来不可能定义也不可能通过ChannelHandler定义ChannelPipeline的某些方面。
不是必需说我们必须定义一个自己和其它的规定。
本节将介绍ChannelHandler和ChannelPipeline在某种程度上细微的依赖。
即使你没有意思到这一点,若果你使用Netty应用将至少有一个ChannelHandler參与。换句话说,ChannelHandler对非常多事情是关键的。那么ChannelHandler到底是什么?给ChannelHandler一个定义不easy,我们能够理解为ChannelHandler是一段运行业务逻辑处理数据的代码,它们来来往往的通过ChannelPipeline。
实际上。ChannelHandler是定义一个handler的父接口,ChannelInboundHandler和ChannelOutboundHandler都实现ChannelHandler接口,例如以下图:
ChannelPipeline的作用我们能够理解为用来管理ChannelHandler的一个容器。每一个ChannelHandler处理各自的数据(比如入站数据仅仅能由ChannelInboundHandler处理),处理完毕后将转换的数据放到ChannelPipeline中交给下一个ChannelHandler继续处理,直到最后一个ChannelHandler处理完毕。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWJjX2tleQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
ChannelOutboundHandler的作用和ChannelInboundHandler同样,它能够传递事件消息到下一个Handler或者自己处理消息。
不同的是ChannelOutboundHandler是从ChannelPipeline的尾部開始。而ChannelInboundHandler是从ChannelPipeline的头部開始,当处理完第一个ChannelOutboundHandler处理完毕后会出发一些操作,比方一个写操作。
每一个都提供了在ChannelPipeline中通过调用对应的方法将事件传递给下一个Handler的方法的实现。
我们能覆盖的方法就是我们须要做的处理。
也就是说Netty中发送消息有两种方法:直接写入通道或写入ChannelHandlerContext对象。
这两种方法的主要差别例如以下:
- 直接写入通道导致处理消息从ChannelPipeline的尾部開始
- 写入ChannelHandlerContext对象导致处理消息从ChannelPipeline的下一个handler開始
3.5 编码器、解码器和业务逻辑:细看Handlers
有几个适配器(adapter)同意自己定义ChannelHandler,一般自己定义ChannelHandler须要继承编码/解码适配器类中的一个。Netty有一下适配器:
- ChannelHandlerAdapter
- ChannelInboundHandlerAdapter
- ChannelOutboundHandlerAdapter
三个ChannelHandler涨,我们重点看看ecoders,decoders和SimpleChannelInboundHandler<I>。SimpleChannelInboundHandler<I>继承ChannelInboundHandlerAdapter。
3.5.1 Encoders(编码器), decoders(解码器)
这样的转换一般发生在网络程序中,由于网络上仅仅能传输字节数据。
重写的channelRead方法将调用每一个解码器的“decode”方法并通过ChannelHandlerContext.fireChannelRead(Object
msg)传递给ChannelPipeline中的下一个ChannelInboundHandler。
3.5.2 业务逻辑(Domain logic)
所以应用程序仅仅须要扩展SimpleChannelInboundHandler<I>,也就是我们自己定义一个继承SimpleChannelInboundHandler<I>的handler类,当中<I>是handler能够处理的消息类型。
通过重写父类的方法能够获得一个ChannelHandlerContext的引用,它们接受一个ChannelHandlerContext的參数,你能够在class中当一个属性存储。
幸运的是Netty提供了解决方式,我们能够在加入ChannelHandler到ChannelPipeline中时指定一个EventExecutorGroup,EventExecutorGroup会获得一个EventExecutor。EventExecutor将运行ChannelHandler的全部方法。EventExecutor将使用不同的线程来运行和释放EventLoop。
Netty In Action中文版 - 第三章:Netty核心概念的更多相关文章
- Netty In Action中文版 - 第六章:ChannelHandler
本章介绍 ChannelPipeline ChannelHandlerContext ChannelHandler Inbound vs outbound(入站和出站) 接受连接或创建他们仅仅是你的应 ...
- Netty In Action中文版 - 第五章:Buffers(缓冲)
本章介绍 ByteBuf ByteBufHolder ByteBufAllocator 使用这些接口分配缓冲和运行操作 每当你须要数据传输时,它必须包括一个缓冲区.Java NIO API自带的缓冲区 ...
- Netty In Action中文版 - 第四章:Transports(传输)
本章内容 Transports(传输) NIO(non-blocking IO,New IO), OIO(Old IO,blocking IO), Local(本地), Embedded(嵌入式) U ...
- Netty In Action中文版 - 第七章:编解码器Codec
http://blog.csdn.net/abc_key/article/details/38041143 本章介绍 Codec,编解码器 Decoder,解码器 Encoder,编码器 Netty提 ...
- Java Persistence with MyBatis 3(中文版) 第三章 使用XML配置SQL映射器
关系型数据库和SQL是经受时间考验和验证的数据存储机制.和其他的ORM 框架如Hibernate不同,MyBatis鼓励开发者可以直接使用数据库,而不是将其对开发者隐藏,因为这样可以充分发挥数据库服务 ...
- Netty 源码解析(三): Netty 的 Future 和 Promise
今天是猿灯塔“365篇原创计划”第三篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源码解析(二): Netty 的 Channel 当前:Ne ...
- Netty In Action中文版 - 第一章:Netty介绍
本章介绍 Netty介绍 为什么要使用non-blocking IO(NIO) 堵塞IO(blocking IO)和非堵塞IO(non-blocking IO)对照 Java NIO的问题和在Nett ...
- Netty In Action中文版 - 第十五章:选择正确的线程模型
http://blog.csdn.net/abc_key/article/details/38419469 本章介绍 线程模型(thread-model) 事件循环(EventLoop) 并发(Con ...
- Netty In Action中国版 - 第二章:第一Netty程序
本章介绍 获得Netty4最新的版本号 设置执行环境,以构建和执行netty程序 创建一个基于Netty的server和client 拦截和处理异常 编制和执行Nettyserver和client 本 ...
随机推荐
- 嵌入式ROOTFS transplantation
作一个嵌入式Linux rootfs,并且实现 web 服务 1. 文件系统简介 •理论上说一个嵌入式设备如果内核能够运行起来,且不需要运行用户进程的话,是不需要文件系统的,文件系统简单的说就是一种目 ...
- codeforcess水题100道
之所以在codeforces上找这100道水题的原因是为了巩固我对最近学的编程语言的掌握程度. 找的方式在codeforces上的PROBLEMSET中过的题最多的那些题里面出现的最前面的10个题型, ...
- linux个性化定制登录信息
1./etc/motd /etc/motd即messageoftoday(布告栏信息),每次用户登录时,/etc/motd文件的内容会显示在用户的终端.系统管理员可以在文件中编辑系统活动消息,例如:管 ...
- echarts - 特殊需求实现方案汇总
五分钟上手echarts echarts中 设置x||y轴文案.提示文字等为固定字数,超出显示"..." 关于echarts下钻功能的一些总结.js echarts - 特殊需求实 ...
- Egret中的三种单例写法
1 普通的单例写法 as3中也是这么个写法. 缺点:每个单例类里都要写instance和getInstance. class Single{ private static instance:Singl ...
- iOS 通过(lame)将录制音频转换成Mp3
版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明出处,保留原帖地址及作者署名. Url:http://blog.csdn.net/ysy441088327/article/detail ...
- Java秒杀简单设计二:数据库表和Dao层设计
Java秒杀简单设计二:数据库表Dao层设计 上一篇中搭建springboot项目环境和设计数据库表 https://www.cnblogs.com/taiguyiba/p/9791431.html ...
- Spring Cloud Eureka 配置
实例名配置 在Netflix Eureka的原生实现中,实例名采用主机名作为默认值,这样的设置使得在同一主机上无法启动多个相同的实例,所以在Spring Cloud Eureka的配置中, ...
- thinkCMF----使用自定义函数
thinkCMF使用自定义函数:app 下新建 common.php
- CentOS7.5安装Tomcat8
一.tomcat的简介 这是Apache Tomcat Servlet / JSP容器的文档包的顶级入口点 .的Apache Tomcat 8.0版实现了Servlet 3.1和JavaServer ...