Netty Review - 深入理解Netty: ChannelHandler的生命周期与事件处理机制

简介: Netty Review - 深入理解Netty: ChannelHandler的生命周期与事件处理机制


概述

Netty的ChannelHandler是处理网络事件(如数据读取、数据写入、连接建立、连接关闭等)的核心组件。

在Netty中,ChannelHandler生命周期Channel的状态紧密相关,主要涉及到以下几个阶段:

  1. 初始化(Initialization):
  • handlerAdded 方法被调用,这通常发生在ChannelPipeline初始化时,表示一个新的ChannelHandler被加入到ChannelPipeline中。
  1. 注册(Registration):
  • channelRegistered 方法被调用,这表示Channel已经成功注册到它的EventLoop上。
  1. 激活(Activation):
  • channelActive 方法被调用,表示Channel已经成功激活,可以开始接收和发送数据。
  1. 读取数据(Read):
  • channelRead 方法被调用,这表示从Channel中读取到了数据。
  1. 读完成(Read Complete):
  • channelReadComplete 方法被调用,这表示一次读取操作完成。
  1. 关闭(Deactivation):
  • channelInactive 方法被调用,表示Channel与远端主机失去了连接,变成了非激活状态。
  1. 注销(Deregistration):
  • channelUnregistered 方法被调用,表示Channel从它的EventLoop上注销。
  1. 移除(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的状态紧密相关,主要涉及到以下几个回调方法:

  1. handlerAdded: 当一个新的ChannelHandler被添加到ChannelPipeline时调用。
  2. channelRegistered: 当Channel成功注册到EventLoop上时调用。
  3. channelActive: 当Channel激活,可以开始接收和发送数据时调用。
  4. channelRead: 当从Channel中读取到数据时调用。
  5. channelReadComplete: 当一次读取操作完成时调用。
  6. channelInactive: 当Channel变为非激活状态时调用。
  7. channelUnregistered: 当Channel从EventLoop上注销时调用。
  8. handlerRemoved: 当ChannelHandler从ChannelPipeline中移除时调用。

以上是Netty ChannelHandler生命周期的主要回调方法,开发者可以根据需要重写这些方法来实现自定义的逻辑处理。


验证

客户端建立连接 ,完成一次消息交互

客户端断开连接


相关文章
|
4月前
|
Java 调度
Netty运行原理问题之ChannelHandler在Netty中扮演什么角色
Netty运行原理问题之ChannelHandler在Netty中扮演什么角色
|
4月前
|
调度
Netty运行原理问题之事件调度工作的问题如何解决
Netty运行原理问题之事件调度工作的问题如何解决
|
7月前
|
存储 缓存 运维
时间轮奇妙旅程:深度解析Netty中的时间轮机制
时间轮奇妙旅程:深度解析Netty中的时间轮机制
256 1
|
7月前
|
前端开发 UED
Netty Review - Netty自动重连机制揭秘:原理与最佳实践
Netty Review - Netty自动重连机制揭秘:原理与最佳实践
226 0
|
7月前
|
监控 网络协议 调度
Netty Review - 深入探讨Netty的心跳检测机制:原理、实战、IdleStateHandler源码分析
Netty Review - 深入探讨Netty的心跳检测机制:原理、实战、IdleStateHandler源码分析
429 0
|
7月前
|
编解码
Netty Review - 优化Netty通信:如何应对粘包和拆包挑战_自定义长度分包编解码码器
Netty Review - 优化Netty通信:如何应对粘包和拆包挑战_自定义长度分包编解码码器
97 0
|
7月前
|
网络协议
Netty Review - 优化Netty通信:如何应对粘包和拆包挑战
Netty Review - 优化Netty通信:如何应对粘包和拆包挑战
108 0
|
7月前
|
缓存 前端开发 Java
Netty Review - Netty与Protostuff:打造高效的网络通信
Netty Review - Netty与Protostuff:打造高效的网络通信
92 0
|
存储 缓存 NoSQL
跟着源码学IM(十一):一套基于Netty的分布式高可用IM详细设计与实现(有源码)
本文将要分享的是如何从零实现一套基于Netty框架的分布式高可用IM系统,它将支持长连接网关管理、单聊、群聊、聊天记录查询、离线消息存储、消息推送、心跳、分布式唯一ID、红包、消息同步等功能,并且还支持集群部署。
13506 1
|
7月前
|
消息中间件 Oracle Dubbo
Netty 源码共读(一)如何阅读JDK下sun包的源码
Netty 源码共读(一)如何阅读JDK下sun包的源码
132 1