博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty Decoder:ByteToMessageDecoder
阅读量:4577 次
发布时间:2019-06-08

本文共 3616 字,大约阅读时间需要 12 分钟。

 1. ByteToMessageDecoder

  这个类是解码器的基类,其中描述了解码器基本的工作方式和实现原理;;还定义了一个解码的抽象方法decode,这个方法由业务实现,负责将一段字节数据解码为具体的消息对象。

// 存储接收到的数据    ByteBuf cumulation;    private boolean first;        @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        if (msg instanceof ByteBuf) {            CodecOutputList out = CodecOutputList.newInstance();            try {                ByteBuf data = (ByteBuf) msg;                first = cumulation == null;                if (first) {                    // 如果 ByteBuf 为空,则将 ByteBuf 指向接收到的消息                    cumulation = data;                } else {                    // 如果 ByteBuf 不为空,则将接收到的数据追加到 ByteBuf                    cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data);                }                // 解码 ByteBuf 中的数据                callDecode(ctx, cumulation, out);            } catch (DecoderException e) {                throw e;            } catch (Throwable t) {                throw new DecoderException(t);            } finally {                 // ByteBuf 中的数据被消费完后,重置消费次数,释放内存,ByteBuf置为null                if (cumulation != null && !cumulation.isReadable()) {                    numReads = 0;                    cumulation.release();                    cumulation = null;                    // ByteBuf 被消费16后压缩消息                } else if (++ numReads >= discardAfterReads) {                      numReads = 0;                    discardSomeReadBytes();                }                // 将解码得到的报文对象全部分发下去                int size = out.size();                decodeWasNull = !out.insertSinceRecycled();                fireChannelRead(ctx, out, size);                out.recycle();            }        } else {            ctx.fireChannelRead(msg);        }    }            // 解码 ByteBuf       protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List out) {        try {            // 如果 ByteBuf 有可读数据就继续解码            while (in.isReadable()) {                                // 如果 out 中有内容,则将内容分发出去,然后清空 out, 并将 outSize 置为 0                int outSize = out.size();                if (outSize > 0) {                    // 将 out 中的所有消息分发出去                    fireChannelRead(ctx, out, outSize);                    // out 存储解码后的报文对象                    // 清空容器()                    out.clear();                    if (ctx.isRemoved()) {                        break;                    }                    outSize = 0;                }                // 解码之前的可读长度                int oldInputLength = in.readableBytes();                // 调用自定义的解码器                decode(ctx, in, out);                if (ctx.isRemoved()) {                    break;                }                // 由上面可知,outSize 为0 ,                // 没有读取数据,没有得到消息对象,则跳出循环                if (outSize == out.size()) {                    if (oldInputLength == in.readableBytes()) {                        break;                    } else {                        continue;                    }                }                 // 没有读取数据,却得到自定义的消息对象,抛出异常                if (oldInputLength == in.readableBytes()) {                    throw new DecoderException(                            StringUtil.simpleClassName(getClass()) +                            ".decode() did not read anything but decoded a message.");                }                if (isSingleDecode()) {                    break;                }            }        } catch (DecoderException e) {            throw e;        } catch (Throwable cause) {            throw new DecoderException(cause);        }    }

 

转载于:https://www.cnblogs.com/virgosnail/p/10492157.html

你可能感兴趣的文章
报表分栏后的排序
查看>>
Django中models定义的choices字典使用get_FooName_display()在页面中显示值
查看>>
nohup命令详解(转)
查看>>
别人的Linux私房菜(1)计算机概论
查看>>
系统编程之文件操作
查看>>
ModelState.IsValid
查看>>
React-Native 环境部署
查看>>
0x27 A*
查看>>
bzoj4872: [Shoi2017]分手是祝愿
查看>>
android底部标题栏的实现
查看>>
[Oracle整理]Oracle之ROWTYPE和RECORD
查看>>
英语语法之一致平衡
查看>>
ats 安全
查看>>
NOI导刊2010提高(06) 黑匣子
查看>>
字节对齐[转]
查看>>
(53)zabbix模板
查看>>
单元测试简介
查看>>
c++的复制构造函数
查看>>
关于大数据你必须了解的几个关键词
查看>>
ansible使用9-Playbooks: Special Topics
查看>>