概述
Netty的ChannelHandler
是处理网络事件(如数据读取、数据写入、连接建立、连接关闭等)的核心组件。
在Netty中,ChannelHandler
的生命周期与Channel
的状态紧密相关,主要涉及到以下几个阶段:
- 初始化(Initialization):
handlerAdded
方法被调用,这通常发生在ChannelPipeline
初始化时,表示一个新的ChannelHandler
被加入到ChannelPipeline
中。
- 注册(Registration):
channelRegistered
方法被调用,这表示Channel
已经成功注册到它的EventLoop
上。
- 激活(Activation):
channelActive
方法被调用,表示Channel
已经成功激活,可以开始接收和发送数据。
- 读取数据(Read):
channelRead
方法被调用,这表示从Channel
中读取到了数据。
- 读完成(Read Complete):
channelReadComplete
方法被调用,这表示一次读取操作完成。
- 关闭(Deactivation):
channelInactive
方法被调用,表示Channel
与远端主机失去了连接,变成了非激活状态。
- 注销(Deregistration):
channelUnregistered
方法被调用,表示Channel
从它的EventLoop
上注销。
- 移除(Removal):
handlerRemoved
方法被调用,表示ChannelHandler
被从ChannelPipeline
中移除。
这些方法的调用顺序与Channel
的状态转换顺序相对应,形成了一个完整的生命周期。在实际应用中,根据不同的需求,开发者可以重写这些方法来实现自定义的逻辑处理,比如处理超时、心跳保活、数据编解码等。
Code
我们还是用 Netty Review - Netty自动重连机制揭秘:原理与最佳实践的代码演示一下 ,在服务端增加一个Handler
ch.pipeline().addLast(new LifeCycleInBoundHandler());
LifeCycleInBoundHandler
package com.artisan.reconnect; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** * handler的生命周期回调接口调用顺序: * handlerAdded -> channelRegistered -> channelActive -> channelRead -> channelReadComplete * -> channelInactive -> channelUnRegistered -> handlerRemoved * * handlerAdded: 新建立的连接会按照初始化策略,把handler添加到该channel的pipeline里面,也就是channel.pipeline.addLast(new LifeCycleInBoundHandler)执行完成后的回调; * channelRegistered: 当该连接分配到具体的worker线程后,该回调会被调用。 * channelActive:channel的准备工作已经完成,所有的pipeline添加完成,并分配到具体的线上上,说明该channel准备就绪,可以使用了。 * channelRead:客户端向服务端发来数据,每次都会回调此方法,表示有数据可读; * channelReadComplete:服务端每次读完一次完整的数据之后,回调该方法,表示数据读取完毕; * channelInactive:当连接断开时,该回调会被调用,说明这时候底层的TCP连接已经被断开了。 * channelUnRegistered: 对应channelRegistered,当连接关闭后,释放绑定的workder线程; * handlerRemoved: 对应handlerAdded,将handler从该channel的pipeline移除后的回调方法。 */ public class LifeCycleInBoundHandler extends ChannelInboundHandlerAdapter { @Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception { System.out.println("channelRegistered: channel注册到NioEventLoop"); super.channelRegistered(ctx); } @Override public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { System.out.println("channelUnregistered: channel取消和NioEventLoop的绑定"); super.channelUnregistered(ctx); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("channelActive: channel准备就绪"); super.channelActive(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("channelInactive: channel被关闭"); super.channelInactive(ctx); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("channelRead: channel中有可读的数据" ); super.channelRead(ctx, msg); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { System.out.println("channelReadComplete: channel读数据完成"); super.channelReadComplete(ctx); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { System.out.println("handlerAdded: handler被添加到channel的pipeline"); super.handlerAdded(ctx); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { System.out.println("handlerRemoved: handler从channel的pipeline中移除"); super.handlerRemoved(ctx); } }
在Netty中,ChannelHandler的生命周期与Channel的状态紧密相关,主要涉及到以下几个回调方法:
handlerAdded
: 当一个新的ChannelHandler被添加到ChannelPipeline时调用。channelRegistered
: 当Channel成功注册到EventLoop上时调用。channelActive
: 当Channel激活,可以开始接收和发送数据时调用。channelRead
: 当从Channel中读取到数据时调用。channelReadComplete
: 当一次读取操作完成时调用。channelInactive
: 当Channel变为非激活状态时调用。channelUnregistered
: 当Channel从EventLoop上注销时调用。handlerRemoved
: 当ChannelHandler从ChannelPipeline中移除时调用。
以上是Netty ChannelHandler生命周期的主要回调方法,开发者可以根据需要重写这些方法来实现自定义的逻辑处理。
验证
客户端建立连接 ,完成一次消息交互
客户端断开连接