Netty学习之入站、出站、handler顺序
Netty4中, I/O事件由ChannelInboundHandler或ChannelOutboundHandler处理,并通过调用ChannelHandlerContext中定义的事件传播方法(如ChannelHandlerContext.fireChannelRead(Object)和ChannelHandlerContext.write(Object))转发给其最接近的处理程序。
Netty4中的所有handler都实现自ChannelHandler接口。按照输入输出来分,分为ChannelInboundHandler、ChannelOutboundHandler两大类。ChannelInboundHandler对从客户端发往服务器的报文进行处理,一般用来执行解码、读取客户端数据、进行业务处理等;ChannelOutboundHandler对从服务器发往客户端的报文进行处理,一般用来进行编码、发送报文到客户端。
下图描述了ChannelPipeline中的ChannelHandlers如何处理I / O事件。
Inbound(入站)事件由Inbound处理程序以自下而上的方向处理,如图所示。Inbound处理程序通常处理由图底部的I/O线程生成的Inbound数据。 Inbound数据通常通过实际的输入操作(如SocketChannel.read(ByteBuffer))从远程对等端读取。 如果Inbound事件超出顶层入站处理程序,它将被静默放弃,或者在需要您关注时进行记录。
一个Outbound(出站)事件由Outbound处理程序在自上而下的方向进行处理,如图所示。Outbound处理程序通常会生成或转换Outbound流量,如写入请求。 如果出站事件超出底部出站处理程序,则由与该通道关联的I / O线程处理。 I/O线程经常执行实际的输出操作,例如SocketChannel.write(ByteBuffer)。
例如,假设我们创建了以下管道:
ChannelPipeline p = ...;
p.addLast("1", new InboundHandlerA());
p.addLast("2", new InboundHandlerB());
p.addLast("3", new OutboundHandlerA());
p.addLast("4", new OutboundHandlerB());
p.addLast("5", new InboundOutboundHandlerX());
在上面的例子中,名称以Inbound开头的类意味着它是一个入站处理程序。名称以Outbound开头的类表示它是出站处理程序。
在给定的示例配置中,当事件进入时,处理程序评估顺序为1,2,3,4,5。当事件出站时,顺序为5,4,3,2,1。在此原则之上,ChannelPipeline跳过某些处理程序的评估以缩短堆栈深度:
- 3和4不实现ChannelInboundHandler,因此入站事件的实际评估顺序将为:1,2和5。
- 1和2不实现ChannelOutboundHandler,因此出站事件的实际评估顺序将为:5,4和3。
- 如果5实现ChannelInboundHandler和ChannelOutboundHandler,则入站和出站事件的评估顺序可分别为125和543。
假设我们现在的Pipeline中的Handler执行器链是这样的:
Pipeline->h1->h2->h3->h4->h5->h6->tail
假设h1,h2,h3是ChannelInboudHadnler入栈处理器,h4,h5,h6是ChannelOutboundHandler出栈处理器
那么Handler的执行顺序是h1->h2->h3->h6->h5->h4,先执行InboundHandler,再反从tail往前找执行OutboundHandler
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!