zoukankan      html  css  js  c++  java
  • 数据处理器ChannelHandler

    ChannelHandler类似于Servlet的Filter过滤器,负责对I/O事件或者I/O操作进行拦截和处理,它可以选择性地拦截和处理自己感兴趣的事件,也可以透传和终止事件的传递。基于ChannelHandler接口,用户可以方便地进行业务逻辑定制,例如打印日志、统一封装异常信息、性能统计和消息编解码等。

    ChannelHandler支持注解,目前支持的注解有两种:

    • @Sharable:多个ChannelPipeline共用同一个ChannelHandler;
    • @Skip:被Skip注解的方法不会被调用,直接被忽略。

    1. ChannelInboundHandlerAdapter

    ChannelInboundHandlerAdapter是ChannelInboundHandler的一个简单实现,默认情况下不会做任何处理,只是简单的将操作通过fire*方法传递到ChannelPipeline中的下一个ChannelHandler,让链中的下一个ChannelHandler去处理。

    需要注意的是信息经过channelRead方法处理之后不会自动释放(因为信息不会被自动释放所以能将消息传递给下一个ChannelHandler处理)。

    (1) SimpleChannelInboundHandler

    SimpleChannelInboundHandler支持泛型的消息处理,默认情况下消息处理完将会被自动释放,无法提供fire*方法传递给ChannelPipeline中的下一个ChannelHandler,如果想要传递给下一个ChannelHandler需要调用ReferenceCountUtil#retain方法。

    一般用netty来发送和接收数据都会继承SimpleChannelInboundHandler和ChannelInboundHandlerAdapter这两个抽象类。

    其实用这两个抽象类是有讲究的,在客户端的业务Handler继承的是SimpleChannelInboundHandler,而在服务器端继承的是ChannelInboundHandlerAdapter。

    最主要的区别就是SimpleChannelInboundHandler在接收到数据后会自动release掉数据占用的Bytebuffer资源(自动调用Bytebuffer.release())。而为何服务器端不能用呢,因为我们想让服务器把客户端请求的数据发送回去,而服务器端有可能在channelRead方法返回前还没有写完数据,因此不能让它自动release。

    2. ChannelOutboundHandlerAdapter

    表示出去的动作,监听自己的IO操作,比如connect,bind等,在重写这个Adapter的方法时,记得执行super.xxxx,否则动作无法执行。

    Netty 中的事件分为inbound 事件和outbound 事件。inbound 事件通常由I/O线程触发,例如TCP 链路建立事件、链路关闭事件、读事件、异常通知事件等。Outbound 事件通常是I/O 用户主动发起的网络I/O 操作,例如用户发起的连接操作、绑定操作、消息发送等操作。

    3. 两者的常用事件

    我们常用的inbound事件有:

    • hannelRegistered(ChannelHandlerContext) //channel注册事件
    • channelActive(ChannelHandlerContext)//通道激活时触发,当客户端connect成功后,服务端就会接收到这个事件,从而可以把客户端的Channel记录下来,供后面复用
    • exceptionCaught(ChannelHandlerContext, Throwable)//出错时会触发,做一些错误处理
    • userEventTriggered(ChannelHandlerContext, Object)//用户自定义事件
    • channelRead(ChannelHandlerContext, Object) //当收到对方发来的数据后,就会触发,参数msg就是发来的信息,可以是基础类型,也可以是序列化的复杂对象。

    常用的outbound事件有:

    • bind(ChannelHandlerContext ctx, SocketAddress localAddress,ChannelPromise promise) //服务端执行bind时,会进入到这里,我们可以在bind前及bind后做一些操作
    • connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) //客户端执行connect连接服务端时进入
    • write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)//发送事件
    • flush(ChannelHandlerContext ctx) //刷新事件

    ChannelPromise是ChannelFuture的扩展,允许设置I/O操作的结果,使ChannelFutureListener可以执行相关操作。

  • 相关阅读:
    Android Media Playback 中的MediaPlayer的用法及注意事项(二)
    Android Media Playback 中的MediaPlayer的用法及注意事项(一)
    34. Search for a Range
    33. Search in Rotated Sorted Array
    32. Longest Valid Parentheses
    31. Next Permutation下一个排列
    30. Substring with Concatenation of All Words找出串联所有词的子串
    29. Divide Two Integers
    28. Implement strStr()子串匹配
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/myitnews/p/12213568.html
Copyright © 2011-2022 走看看