ChannelInboundHandler

📅 发布时间:2026/8/9 4:45:36
ChannelInboundHandler
一、先理清核心前提ChannelInboundHandler本身既能处理入栈事件也可以执行出站发送逻辑1、为什么入栈 Handler 里既能写channelRead/channelActive又能调用ctx.writeAndFlush()发数据1channelActive、channelRead本身就是入栈事件回调channelActive底层内核通知连接就绪网络方向「内核→应用」入栈channelRead服务器发过来数据包内核读到数据往上抛给应用入栈 这两个方法是响应从底层上来的网络信号所以写在ChannelInboundHandler里。2在入栈 Handler 中调用ctx.writeAndFlush()属于主动发起出站动作write()/writeAndFlush()是你主动向上层接口发起 “要发数据到网络” 的请求这个请求会沿着 Pipeline 做出站方向流转和当前 Handler 是入栈类型没有冲突Handler 的类型决定它擅长拦截处理哪一类事件不代表它不能触发另一类事件入栈 Handler 只对入栈事件有默认处理逻辑你手动调用写数据是主动触发出站流程。举个通俗例子 快递驿站InboundHandler本职是接收快递入栈服务器发来数据、连接就绪通知 你在驿站拿到快递之后顺手寄一个快递回去主动调用 write 发消息驿站本身依然是收件的角色只是你顺便发起寄件。2、ChannelInboundHandler、ChannelOutboundHandler 的本质分工① ChannelInboundHandler监听「从网络底层向上到达应用」的事件负责接收底层推送过来的信号channelRegistered / channelUnregisteredchannelActive连上、channelInactive断开channelRead、channelReadComplete读到对方发的数据exceptionCaught 异常② ChannelOutboundHandler拦截「应用往下发往网络」的出站操作拦截业务发起的向下操作 connect、bind、write、flush、close、disconnect。 它的定位不是 “发数据”而是在数据真正下发到底层之前做拦截加工编码、加解密、流量统计、限流、修改报文、添加协议头部、压缩数据、日志打印发包内容等。二、那专门的 OutboundHandler 到底有什么不可替代的作用你疑惑既然入栈 Handler 里随手就能 write 发数据还要出站处理器干什么作用 1统一拦截所有向外发送的数据做全局预处理典型场景编码你业务层发 Java 对象需要序列化成二进制字节流再发出去自定义协议封装给数据包加长度头、校验码、消息类型标记发包日志记录每一条发出去的报文内容数据加密、压缩、限流、超时重发判断 这些逻辑必须在数据往下发送的路上拦截处理只能写在ChannelOutboundHandler。对应你截图里的MESSAGE_CODEC 里面的编码器部分本质就是一个出站处理器业务写出对象 → 经过出站编码器序列化 bytebuf → 再交给底层发送。作用 2拦截连接、关闭、绑定这类出站指令拦截connect拦截客户端发起连接做连接前置校验、动态修改目标连接地址拦截close拦截关闭连接请求关闭前强制刷完缓冲区数据、记录下线日志、释放资源 普通入栈 Handler 没法拦截这些操作。作用 3Pipeline 双向执行路径天然分离职责解耦Pipeline 是一条链两类事件遍历方向不一样入栈事件active/readtail→ 倒序走到head出站操作write/connecthead→ 正序走到tail举你的整条 Pipeline 顺序ProcotolFrameDecoder→ LOGGING_HANDLER → MESSAGE_CODEC → client handler服务端数据过来入栈从 tail 开始先走 client handler→CODEC→日志→解码器你在 client handler 执行 write出站从 head 开始先走解码器→日志→CODEC 编码器→client handler 编码器放在靠前位置所有出站数据都会优先经过它序列化这就是出站 Handler 的价值。作用 4、职责拆分代码规范解耦InboundHandler只管收消息、连接状态、业务响应处理OutboundHandler只管发消息之前的加工、发包管控、连接关闭管控 不会出现一段代码既要处理接收逻辑又混杂发包编码、协议封装结构清晰。三、完整走一遍流程TCP 握手成功触发channelActive入栈事件反向遍历 Pipeline 执行你的 client handler你在该方法里新开线程输入账号密码执行ctx.writeAndFlush(message)write 是出站操作正向遍历整条 Pipeline MESSAGE_CODEC 的出站编码器把 LoginRequestMessage 序列化为二进制 LOGGING_HANDLER 打印发包日志 ProcotolFrameDecoder 只处理入栈拆包出站不会生效最后交给底层 NIO 发送到服务器服务器返回响应数据触发 channelRead 入栈再次反向走到你的 client handler 接收解析。四、一句话总结InboundHandler等着网络主动推送消息、连接状态通知被动接收里面可以手动调用 write 主动发起发包OutboundHandler不负责 “触发发送”而是所有往外发的数据、连接、关闭动作必经的拦截加工节点做编码、协议封装、监控、拦截控制是 Netty 分层架构必不可少的一环。