Netty笔记(五)ChannelHandler

本文详细解析了Netty中的ChannelPipeline和ChannelHandler的使用方式,包括ChannelPipeline的动态管理、事件处理机制、ChannelHandlerContext的作用,以及不同类型的ChannelHandler(InboundHandler、OutboundHandler)和其关键事件方法的应用。

    Netty中ChannelHandler 抽象了接口, 在ChannelPipeline中执行,覆盖的事件处理方法,让其写出更简介,处理逻辑。

    ChannelPipeline中通过不同的ChannelHandlers处理I/O,对应I/O操作,ChannelPipeline中对应使用ChannelInboundHandler或ChannelOutboundHandler执行。而这些方法定义在ChannelInboundInvoker和ChannelOutboundInvoker中。

    ChannelPipeline 可以在运行时,动态的添加修改或删除相应ChannelHandler,提供了

addFirst、addBefore、addAfter、addLast、remove、replace等这些操作方法。

    ChannelPipline中执行ChannelHandlers是在单线程中执行,这就意味着我们在ChannelHandlers中不应该写入阻塞的代码。这将直接影响后面的Handler运行。

    ChannelPipline还提供了获取他之中的ChannelHandler方法:

get、context、contains、names、iterator等这些操作方法。

    ChannelPipline还继承自ChannelInboundInvoker跟ChannelOutboundInvoker,这意味着他提供了许多事件通知执行方法,诸如fireChannelRegistered()这些操作。ChannelOutboundInvoker 则定义了诸如write、flush、bind这些操作。


    ChannelHandlerContext  一个上下文对象。当一个ChannelHandler被加入到ChannelPipleline中,会新创建一个ConnalHandlerContext ,并绑定到改ChannelHandler中。

    ChannelHandlerContext同样实现了ChannelInboundInvoker跟ChannelOutboundInvoker。

    跟ChannlePipeline和ChannelHadnler的关系

前面提到ChannelHandlerContext跟ChannlePipeline都实现了ChannelOutboundInvoker,但他们调用wirte方法时,在netty的事件机制定义下,事件执行的顺序则在ChannelPipeline的中ChannelHandlers的顺序跟方式则不一样。

    Channel 跟 ChannelPipeline 都可以通过write方法对客户端写数据,其中write方法写入并不会立即写出,会写入到队列中,除非 flush,则会立即写出。

    使用Channel跟ChannelPipleline的write,则会触发事件,经过所有实现了ChannlOutboundHandler的ChannelHandler执行。

    而使用ChannelHandlerContext中的write方法,则会出发在ChannelPipeline中当前执行ChannelHandlerContext的ChannelHandler它的一个ChannelHandler继续执行。

    我们想在多个ChannelPipeline中使用一个ChannelHandler实例,可在ChannelHandler类定义中加入@Sharable注解。在每次执行方法时,方法传入的ChannelHandlerContext则是对应他们所在ChannelPipeline创建并为他绑定的实例。

    ChannelHandler 类型有两类:

Inbound Handler : 处理接收到的数据跟改化他们的状态。

Outbound Handler : 处理要发出去的数据跟可以中断不同的操作。


ChannelHandler的几个事件

handleAddad() , 在生加入 ChannelPipeline执行。

handleRemoved(), 在ChannelPipeline中移除执行。

exceptionCatch(),当在ChannelPipeline中处理时发生异常被捕获。


ChannelInboundHandler 的几个重要方法:

channelRegistered()     :Channel在EventLoop中注册时执行,并开始执行I/O操作。

channelUnRegistered()  :当Channel在EventLoop中注销时执行,已玩I/O操作。

channelActive() : Channel在connected/bound时执行。

channelInActive() : Channel在disconnected执行。

channelReadComplete():当一次读操作执行完成时间执行。 

channelRead():读取到数据时执行。

userEventTriggered():用户在定制的事件中触发。


ChannelInboundHandler 的几个封装的类:

ChannelInboundHandlerAdapter

不释放ByteBuf资源,需要用ReferenceCountUtil.release(..)操作执行释放

SimpleChannelInboundHandler

自动释放 ByteBuf资源。

由于netty对ByteBuf进行池化管理 , 主要是"ReferenceCount"的方式,资源避免泄露,则需要释放。


ChannelOutboundHandler 的几个重要方法:

bind() : Channel绑定的网络地址时触发。

connect():Channel进行连接时触发。

diaconect():Channel关闭连接时触发。

close() :Channel关闭时触发。

deregister():Channel在EventLoop中注销触发。

read():当须要Channel读取更多的数据时触发。

flush():让列队数据写的数据写到客户端/服务端时触发。

write():写数据到客户端/服务端时触发。


转载于:https://my.oschina.net/XzhiF/blog/264731

### 关于 Netty 的学习笔记教程 #### 什么是 NettyNetty 是一个异步事件驱动的网络应用程序框架,旨在快速开发可维护的高性能协议服务器和客户端[^1]。它广泛应用于 Java 领域中的高并发场景,例如分布式系统、微服务通信以及实时消息传递。 --- #### 黑马程序员 Netty 学习资源推荐 以下是针对 Netty 学习的一些优质资料汇总: 1. **官方文档** 官方文档是最权威的学习材料之一,涵盖了从入门到高级的各种主题。可以通过阅读官方指南了解 Netty 的核心概念及其 API 使用方式。 2. **GitHub 和 Gitee 上的 Demo 案例仓库** 提供了一个名为 `netty-learn` 的项目库,分别托管在 GitHub 和 Gitee 平台上。这些仓库包含了丰富的实践案例,帮助开发者更好地理解和掌握 Netty 的实际应用场景。 - GitHub 地址:[https://github.com/](https://github.com/) - Gitee 地址:[https://gitee.com/](https://gitee.com/) 3. **黑马程序员相关课程** 黑马程序员提供了全面的 Java 架构师培训体系,其中包括 Dubbo、Redis、ZooKeeper、Spring Cloud 等技术栈的内容,同时也覆盖了 Netty 的基础知识和实战技巧[^2]。具体可以关注其官网或者联系客服获取最新课程安排。 4. **核心技术解析** - 创建 NioEventLoopGroup 实现线程池加 Selector 功能[^3]。 - Bootstrap 初始化流程详解,包括线程池配置、通道类型设定、Socket 参数调整以及 ChannelHandler 注册等内容[^4]。 - 单例模式下的 @ChannelHandler.Sharable 注解作用说明。 --- #### 示例代码片段 以下是一个简单的 Netty 客户端启动过程演示: ```java import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; public class NettyClient { public static void main(String[] args) throws Exception { EventLoopGroup group = new NioEventLoopGroup(); // (1) try { Bootstrap bootstrap = new Bootstrap(); // (2) bootstrap.group(group) // (3) .channel(NioSocketChannel.class) // (4) .handler(new ClientInitializer()); // (6) ChannelFuture future = bootstrap.connect("localhost", 8080).sync(); // (7) future.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } } ``` 上述代码展示了如何利用 Netty 开发基本的客户端程序,涉及到了多个重要环节的操作步骤。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值