Netty内置处理器整理

背景

Netty提供了很多内置的处理器,高效地利用这些处理器,可以经过简单的配置就可以实现部分复杂功能,而不是自己花时间和精力去重复造“轮子”。
要使用,得先知道,本文主要依据《netty实战》一书进行的梳理,结合了实际应用经验进行了整理。

解码器

ByteToMessageDecoder:是最基础的解码器,将字节数组解析为消息。
ReplayingDecoder:继承自ByteToMessageDecoder,使得我们不必调用readableBytes()方法来判断是否有足够的数据可被读取。
LineBasedFrameDecoder:使用了行尾控制字符(\n 或者\r\n)来解析消息数据。
MessageToMessageDecoder:将一种消息的格式转换为另外一种。
HttpObjectAggregator:同样是解码器的一个子类,非常复杂,处理http请求。

注意:由于Netty 是一个异步框架,所以需要在字节可以解码之前在内存中缓冲它们。因此,不能让解码器缓冲大量的数据以至于耗尽可用的内存。为了解除这个常见的顾虑,Netty 提供了TooLongFrameException 类,其将由解码器在帧超出指定的大小限制时抛出。

编码器

MessageToByteEncoder:最基本的编码器,将消息编码为字节数组。
MessageToMessageEncoder:将一种消息的格式转换为另外一种。

编解码器

编解码器可以在同一个类中管理入站和出站数据和消息的转换。
ByteToMessageCodec:基类,同时实现了ChannelInboundHandler 和ChannelOutboundHandler 接口,但不是直接实现,而是间接实现。

public abstract class ByteToMessageCodec extends ChannelDuplexHandler
public class ChannelDuplexHandler extends ChannelInboundHandlerAdapter implements ChannelOutboundHandler

MessageToMessageCodec:消息间的编解码。

从重用的角度来说,将编码和解码放到一个类中管理会丧失灵活性,这里有一种途径来解决该问题,使用CombinedChannelDuplexHandler。这个类充当了ChannelInboundHandler 和ChannelOutboundHandler(该类的类型参数I 和O)的容器。

public class CombinedByteCharCodec extends CombinedChannelDuplexHandler<ByteToCharDecoder, CharToByteEncoder> {
    public CombinedByteCharCodec() {
        super(new ByteToCharDecoder(), new CharToByteEncoder());
    }
}

安全传输

SslHandler:用于加密传输。

Http请求

Http编解码器

HttpServerCodec:服务端,进行http编码和解码,实际是HttpRequestDecoder和HttpResponseEncoder两个的组合。
HttpClientCodec:客户端,进行http编码和解码,实际是HttpRequestEncoder和HttpResponseDecoder两个的组合。

这里用到了我们上章提到的复合编解码器的CombinedChannelDuplexHandler

public final class HttpClientCodec 
    extends CombinedChannelDuplexHandler<HttpResponseDecoder, HttpRequestEncoder>
    implements HttpClientUpgradeHandler.SourceCodec

Http聚合器

HttpObjectAggregator:http消息通常是多部分组成,以请求为例,通常由HttpHeader、HttpContent(1个或多个)、LastHttpContent,该处理器可以将tcp多次传输的结果组合为一个完整的http请求。

Http压缩解压器

压缩与解压是为了提高性能。
HttpContentCompressor,放在服务端。
HttpContentDecompressor,放在客户端。

WebSocket处理器

WebSocketServerProtocolHandle:负责处理服务端的握手和控制(Ping、Pong、Close),不负责TextWebSocketFrame、BinaryWebSocketFrame和ContinuationWebSocketFrame。

空闲的连接和超时


IdleStateHandler:空闲检测,通常用于心跳保持,可分别设置读空闲、写空闲和读写都空闲的时间。

pipeline.addLast(new IdleStateHandler(5,0,0, TimeUnit.SECONDS));

如超出后,可触发空闲事件,由下个处理器在userEventTriggered中处理:

public class HeartbeatTimeoutHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof IdleStateEvent){
            IdleStateEvent event=(IdleStateEvent)evt;
            if(event.state().equals(IdleState.READER_IDLE)){
                log.info("读空闲");
            }
        }else{
            //非空闲事件,传递到下个处理器
            super.userEventTriggered(ctx,evt);
        }

    }
}

netty不仅内置了灵活性最大的IdleStateHandler,实际还内置了两个可以直接使用的读超时和写超时处理器,对于心跳机制,如果是客户端发心跳请求,服务端发心跳响应,那么我们完全可以直接使用ReadTimeoutHandler,而不需要使用IdleStateHandler+自定义处理器实现。

解码基于分隔符的协议和基于长度的协议

DelimiterBasedFrameDecoder:使用任何由用户提供的分隔符来提取帧的通用解码器。
LineBasedFrameDecoder:提取由行尾符(\n 或者\r\n)分隔的帧的解码器。
FixedLengthFrameDecoder:提取在调用构造函数时指定的定长帧。
LengthFieldBasedFrameDecoder:根据编码进帧头部中的长度值提取帧;该字段的偏移量以及长度在构造函数中指定。

写大型数据

如果是直接传输文件内容,不做处理,建议使用FileRegion来实现,充分利用零拷贝特性。

如还需要对文件内容处理,则netty内置了ChunkedWriteHandler,不会消耗大量内存,但是需要结合以下类使用:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学海无涯,行者无疆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值