本章不会直接分析Netty源码,而是通过使用Netty的能力实现一个自定义协议的服务器和客户端.通过这样的实践,可以更深刻地理解Netty的相关代码,同时可以了解,在设计实现自定义协议的过程中需要解决的一些关键问题. 本周章涉及到的代码可以从github上下载: https://github.com/brandonlyg/tinytransport.git. 设计协议 本章要设计的协议是基于TCP的应用层协议.在设计一个协议之前需要先回答以下几个问题: 使用场景是什么? 这个协议有哪些功能? 性…
io.netty.handler.timeout.IdleStateHandler功能是监测Channel上read, write或者这两者的空闲状态.当Channel超过了指定的空闲时间时,这个Handler会触发一个IdleStateEvent事件. 在第一次检测到Channel变成active状态时向EventExecutor中提交三个延迟任务: ReaderIdleTimeoutTask: 检测read空闲超时. WriterIdleTimeoutTask: 检测write空闲超时. A…
编解码框架和一些常用的实现位于io.netty.handler.codec包中. 编解码框架包含两部分:Byte流和特定类型数据之间的编解码,也叫序列化和反序列化.不类型数据之间的转换. 下图是编解码框架的类继承体系: 其中MessageToByteEncoder和ByteToMessageDecoder是实现了序列化和反序列化框架. MessageToMessage是不同类型数据之间转换的框架. 序列化抽象实现: MessageToByteEncoder<I> 序列化是把 I 类型的数据转换…
数据包编解码过程中主要的工作就是:在编码过程中进行序列化,在解码过程中从Byte流中分离出数据包然后反序列化.在MessageToByteEncoder中,已经解决了序列化之后的问题,ByteToMessageDecoder中已经部分第解决了从Byte流中分离出数据包的问题.实现具体的数据包编解码,只需要实现MessageToByteEncoder的encode和ByteToMessageDecoder的decode方法即可. 为了方便开发者使用Netty,在io.netty.handler.c…
本章开始分析ChannelHandler实现代码.ChannelHandler是netty为开发者提供的实现定制业务的主要接口,开发者在使用netty时,最主要的工作就是实现自己的ChannelHandler.ChannelHandler在设计上需要和ChannelPipeline配合共同实现pipeline的事件传递能力,这要求ChannelHandler需要实现一些固定的基本功能.由于这个原因,如果让用户自己完整地实现,会显得比较麻烦.为此netty实现类一系列的类来帮助开发者以简单的方式实…
  结构设计 Channel的NIO实现位于io.netty.channel.nio包和io.netty.channel.socket.nio包中,其中io.netty.channel.nio是抽象实现,io.netty.channel.socket.nio最终实现.下面是Channel NIO相关类的派生图: NIO实现最终派生出3个类型NioServerSocketChannel实现了tcp server, NioSocketChannel实现了tcp client, NioDatagram…
事件触发.传递.处理是DefaultChannelPipleline实现的另一个核心能力.在前面在章节中粗略地讲过了事件的处理流程,本章将会详细地分析其中的所有关键细节.这些关键点包括: 事件触发接口和对应的ChannelHandler处理方法. inbound事件的传递. outbound事件的传递. ChannelHandler的eventExecutor的分配. 事件的触发方法和处理方法 netty提供了三种触发事件的方式:通过Channel触发,通过ChannelPipleline触发,…
netty线程体系概览 netty的高并发能力很大程度上由它的线程模型决定的,netty定义了两种类型的线程: I/O线程: EventLoop, EventLoopGroup.一个EventLoopGroup包含多个EventLoop, 每个Channel会被注册到一个,一个EventLoop中, 一个EventLoop可以包含多个Channel.Channel的Unsafe实例的方法必须要在EventLoop中执行(netty中明确指明的不需要在I/O线程中执行的几个方法除外,前面的章节中有…
写数据是NIO Channel实现的另一个比较复杂的功能.每一个channel都有一个outboundBuffer,这是一个输出缓冲区.当调用channel的write方法写数据时,这个数据被一系列ChannelOutboundHandler处理之后,它被放进这个缓冲区中,并没有真正把数据写到socket channel中.然后再调用channel的flush方法,flush会把outboundBuffer中数据真正写到socket channel.正常情况下flush之后,数据已经真正写完了.…
全名: io.netty.channel.Channel Channel内部定义了一个Unsafe类型,Channel定义了对外提供的方法,Unsafe定义了具体实现.我把Channel定义的的方法分为三种类型: 辅助方法. outbound方法 inbound方法 下面依次对这三种方法给予详细说明:   1. 辅助方法 方法 说明 EventLoop eventLoop() 得到EventLoop实例,每个Channel实例都会被注册到一个EventLoop中,这个EventLoop实例就是C…