吃透Netty源码系列三十八之ByteToMessageDecoder详解

本文深入探讨Netty中的ByteToMessageDecoder组件,详细分析其重要属性、工作原理及内部方法,如MERGE_CUMULATOR和COMPOSITE_CUMULATOR累加器,decode抽象方法,channelRead和decodeLast等关键方法,以及FixedLengthFrameDecoder子类的解码过程。

ByteToMessageDecoder

字节到消息的编码器,因此应该是实现入站操作的,这类解码器处理器都不是共享的,因为需要存还没有解码完的数据,还有各种状态,是独立的,不能进行共享。
在这里插入图片描述

重要属性

先看看他的一些属性:

	//状态码
    private static final byte STATE_INIT = 0;//初始状态
    private static final byte STATE_CALLING_CHILD_DECODE = 1;//正在调用子类解码
    private static final byte STATE_HANDLER_REMOVED_PENDING = 2;//处理器待删除

    ByteBuf cumulation;//累加缓冲区
    private Cumulator cumulator = MERGE_CUMULATOR;//默认是合并累加器
    private boolean singleDecode;//是否只解码一次
    private boolean first;//是否是第一次累加缓冲区
 	private boolean firedChannelRead;//自动读取是false的时候,是否要去调用ChannelHandlerContext的read()来设置监听读事件,可能没读完


	//状态
    private byte decodeState = STATE_INIT;
    private int discardAfterReads = 16;//读取16个字节后丢弃已读的
    private int numReads;//cumulation读取数据的次数

内部会维护一个状态decodeState ,以便于如果在执行解码的时候处理器上下文被删除了,可以及时响应。
还有一个累加缓冲区,如果有不能拼成一个消息的数据会放入这个缓冲区里,等待下一次继续拼。当然累加缓冲区怎么累加,就需要有累加器,默认是合并累加器MERGE_CUMULATOR

MERGE_CUMULATOR合并累加器

主要是做一般缓冲区的合并,直接将新的缓冲区拷贝到累加缓冲区中。

    public static final Cumulator MERGE_CUMULATOR = new Cumulator() {
   
   
        @Override
        public ByteBuf cumulate(ByteBufAllocator alloc, ByteBuf cumulation, ByteBuf in) {
   
   
            if (!cumulation.isReadable() && in.isContiguous()) {
   
   //累计的不可读(比如为空缓冲区),且新的是连续的,不是符合缓冲区,释放老的,返回新的
                cumulation.release();
                return in;
            }
            try {
   
   
                final int required = in.readableBytes();
                if (required > cumulation.maxWritableBytes() ||
                        (required > cumulation.maxFastWritableBytes() && cumulation.refCnt() > 1) ||
                        cumulation.isReadOnly()) {
   
   //扩容了

                    return expandCumulation(alloc, cumulation, in);
                }
                cumulation.writeBytes(in, in.readerIndex(), required);//将in写入
                in.readerIndex(in.writerIndex());//in不可读了
                return cumulation;
            } finally {
   
   
                in.release();//返回前要释放in
            }
        }
    };

COMPOSITE_CUMULATOR复合累加器

另一个是复合累加器,也就是处理复合缓冲区,默认累加缓冲区也会是复合缓冲区。如果添加进来的缓冲区不可读,那就什么都不做,也就是复合缓冲区的累加方式。

 public static final Cumulator COMPOSITE_CUMULATOR = new Cumulator() {
   
   
        @Override
        public ByteBuf cumulate(ByteBufAllocator alloc, ByteBuf cumulation, ByteBuf in) {
   
   
            if (!cumulation.isReadable()) {
   
   //不可读了,直接返回in
                cumulation.release();
                return in;
            }
            CompositeByteBuf composite = null
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值