Easy Netty 系列(三):ChannelHandler详解
Handler 是处理器,那它处理什么呢?网络中有什么它就做那些处理,常见的有连接的建立,响应读写事件,网络中数据的处理如编码、解码等,这些都输处理器做的,Netty 中的处理器是ChannelHandler
接口,所有的处理器都是这个接口的实现。
首先说下 Netty 处理器的定位,它是 Netty 架构网络处理与业务逻辑的解耦,处理器代表了与用户相关的业务逻辑,如数据读取后端计算和发送,而网络连接管理、线程控制、网络事件监听处理都由 Netty 接管,使我们可以更加专注业务逻辑,站在开发的角度使用 Netty 开发接触最多的就是ChannelHandler
。
处理器有许多种类,通过以下分类你可以先在脑海中建立一个简单的概念。
处理器分类
- 入站处理器:处理 read 事件的数据,通常是解码操作
- 出站处理器:处理 write 事件的数据,通常是编码操作
- 编解码器:一种专用的数据转换器,例如字节转换为字符串,称之为“解码器”,反之把字符串转换为“字节”称之为“编码器”
- 转换器:复合处理器,把一种数据转换为另一种数据,例如 HTTP1 转换为 HTTP2
ChannelHandler 层次结构
常用类使用
最常使用的是 ChannelInboundHandlerAdapter、ChannelDuplexHandler、ChannelOutboundHandlerAdapter 的实现类,这些类定义了作为不同的类型的方法,例如 InboundHandler 与 OutBoundHandler 定义的方法就有很大的差别。
以入站为代表的方法有 ByteToMessageDecoder、SimpleChannelInboundHandler。
例如ByteToMessageDecoder
使用时重写decode
方法即可,编码器重写 encode
。
public class SquareDecoder extends {@link ByteToMessageDecoder} {
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
throws Exception {
out.add(in.readBytes(in.readableBytes()));
}
}
SimpleChannelInboundHandler<T>
使用时重写 channelRead0
方法即可,Adapter 里已经帮我们做好了类型转换。
public class StringHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String message)
throws Exception {
System.out.println(message);
}
}
ChannelDuplexHandler 的继承类实现多是进行数据转换,例如:ByteToMessageCodec 将入站的 byte 数据转化为对象,出站时将对象转换为 byte,类似的还有 MessageToMessageCodec,实现两个对象间的转化。
ChannelHandler 的几个注意点
1、执行顺序。按照被添加的顺序执行。
2、共享 Handler 与非共享 Handler。共享的 handler 会帮定到多个 Channel,当 Channel 并行执行时可能存在线程安全问题;非共享 handler 绑定时就会创建一个,Channel 独享不存在线程安全问题。
3、Handler 的 read 会执行多次。当 Channel 中的数据未处理完,上一个 handler 会多次触发下个 handler 的 read 事件。
(end)