Netty Review - 深入理解Netty: ChannelHandler的生命周期与事件处理机制
2023-12-24 13:30:00
概述
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生命周期的主要回调方法,开发者可以根据需要重写这些方法来实现自定义的逻辑处理。
验证
客户端建立连接 ,完成一次消息交互
客户端断开连接
文章来源:https://blog.csdn.net/yangshangwei/article/details/135176347
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!