Netty4 ChannelHandler 概述
本节主要介绍 Netty ChannelHandler 事件概述,并详细介绍各个事件方法的触发时机,为下篇关于事件传播机制打下坚实基础。
NIO 相关的核心类图如下:
下面一一对上述类做一个简单的介绍,下文还会其进行更为详细的解读。
- ChannelHandler
Netty Channel事件的基础接口,只定义与 Handler 的管理接口相关,具体如下:- void handlerAdded(ChannelHandlerContext ctx)
在调用 DefaultChannelPipeline 的 addLast(add*) 将事件监听器添加到事件处理链条时调用。 - void handlerRemoved(ChannelHandlerContext ctx)
在调用DefaultChannelPipeline 的 addLast(add*) 发生异常时被调用;当通道关闭后,通道取消注册后,同时会触发通道移除事件,具体调用入口:DefaultChannelPipeline 的内部类 HeadContext 的 channelUnregistered。
- void handlerAdded(ChannelHandlerContext ctx)
- ChannelInboundHandler
入端类型的事件处理器。- void channelRegistered(ChannelHandlerContext ctx)
通道注册到 Selector 时触发。客户端在调用 connect 方法,通过 TCP 建立连接后,获取 SocketChannel 后将该通道注册在 Selector 时或服务端在调用bind 方法后创建 ServerSocketChannel,通过将通道注册到 Selector 时监听客户端连接上时被调用。 - void channelUnregistered(ChannelHandlerContext ctx)
通道取消注册到Selector时被调用,通常在通道关闭时触发,首先触发channelInactive 事件,然后再触发 channelUnregistered 事件。 - void channelActive(ChannelHandlerContext ctx)
通道处于激活的事件,在 Netty 中,处于激活状态表示底层 Socket 的isOpen() 方法与 isConnected() 方法返回 true。 - void channelInactive(ChannelHandlerContext ctx)
通道处于非激活(关闭),调用了 close 方法时,会触发该事件,然后触发channelUnregistered 事件。 - void channelRead(ChannelHandlerContext ctx, Object msg)
通道从对端读取数据,当事件轮询到读事件,调用底层 SocketChanne 的 read 方法后,将读取的字节通过事件链进行处理,NIO 的触发入口为AbstractNioByteChannel 的内部类 NioByteUnsafe 的 read 方法。 - void channelReadComplete(ChannelHandlerContext ctx)
处理完一次通道读事件后触发,在 Netty 中一次读事件处理中,会多次调用SocketChannel 的 read方法。触发入口为AbstractNioByteChannel 的内部类NioByteUnsafe 的 read 方法。 - void userEventTriggered(ChannelHandlerContext ctx, Object evt)
触发用户自定义的事件,目前只定义了ChannelInputShutdownEvent(如果允许半关闭(输入端关闭而服务端不关闭))事件。 - void channelWritabilityChanged(ChannelHandlerContext ctx)
Netty 写缓存区可写状态变更事件(可写–》不可写、不可写–》可写),入口消息发送缓存区ChannelOutboundBuffer。
- void channelRegistered(ChannelHandlerContext ctx)
- void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
异常事件。 - ChannelOutboundHandler
出端类型的事件处理器。- void bind(ChannelHandlerContext ctx, SocketAddress add, ChannelPromise p)
调用ServerBootstrap 的 bind 方法的处理逻辑。绑定操作,服务端在启动时调用bind方法时触发(手动调用bind)。 - void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,SocketAddress localAddress, ChannelPromise promise)
连接操作,客户端启动时调用connect方法时触发(手动调用connect)。 - void disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
断开连接操作(手动调用disconnect) - void close(ChannelHandlerContext ctx, ChannelPromise promise)
关闭通道,手动调用Channel#close方法时触发。(手动调用close) - void deregister(ChannelHandlerContext ctx, ChannelPromise promise)
调用Channel#deregister时触发。(手动调用deregister)。 - void read(ChannelHandlerContext ctx) throws Exception
注册读事件,并不是触发网络读写事件。 - void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception
调用调用 Channel 的 write(底层 SocketChannel 的 write)时触发。 - void flush(ChannelHandlerContext ctx)
调用调用Channel#flush(SocketChannel#flush)时触发。
- void bind(ChannelHandlerContext ctx, SocketAddress add, ChannelPromise p)
- ChannelDuplexHandler
双向 Handler,包含 Inbound 和 outbound 事件。 - ByteToMessageDecoder
解码器:字节流解码成一条一条的消息(Message、协议对象)。 - MessageToByteEncoder
编码器:消息(协议对象)编码成二进制字节流。 - AbstractTrafficShapingHandler
流量整形,将在后续章节中详细介绍。
上述详细的介绍了NettyChannel的类继承体系,并重点介绍了ChannelInboundHandler 与 ChannelOutboundHandler 每个方法的含义已经触发时机,接下来再谈一点我对这两个 Handler 的一些理解。
ChannelInboundHandler:入端操作,可以看出基本上是都是由事件选择器(NIO Selector事件就绪选择)进行触发,事件名称以 channel 开头,例如channelRead。
ChannelOutboundHanlder:出端操作,其触发点除了 read 事件外都是通过调用api(例如bind、connect、close、write)。
本文就介绍到这里了,主要目的是让大家对 Netty ChannelHandler 有一个基本的认识,为后续文章打下坚实的基础。
最后以一个思考题结束本文的讲解:ChannelInboundHandler 的channelRead 事件与 ChannelOutboundHandler 的 read 事件有什么区别呢?
温馨提示:如果需要与笔者关于上述问题进行交流,可以加笔者微信:dingwpmz。
好了,本文就介绍到这里了,您的点赞与转发是对我持续输出高质量文章最大的鼓励。
见文如面,我是威哥,热衷于成体系剖析JAVA主流中间件,关注公众号『中间件兴趣圈』,回复专栏可获取成体系专栏导航,回复资料可以获取笔者的学习思维导图。
本文地址:https://blog.csdn.net/prestigeding/article/details/110731038
上一篇: Android实现上下菜单双向滑动
推荐阅读
-
Java面向对象(1)面向对象的思想概述以及类的介绍,封装和构造方法
-
PHP use关键字概述,use关键字概述
-
Oracle服务器体系结构概述
-
Mantis概述
-
ThinkPHP缓存方法S()概述_PHP
-
PHP内核探索:变量概述_PHP教程
-
速战速决 1 - PHP: 概述, 常量, 变量, 运算符, 表达式, 控制语句
-
php数组的概述及分类与声明代码演示_PHP教程
-
4.1 段落样式概述 4.2 下划线、删除线和顶划线text-decoration
-
Android 入门第十讲02-广播(广播概述,使用方法(系统广播,自定义广播,两个activity之间的交互和传值),EventBus使用方法,数据传递,线程切换,Android的系统广播大全)