12、Decoder解码器和Encoder编码器

decoder部分:

decoder解码器是将Byte解析成为List的Java pojo对象。所有netty中的解码器,都是Inbound入站处理器类型,
都直接或者间接实现了ChannelInboundHandler接口。
每个解码器都是一个InboundHander

decoder–>ByteToMessageDecoder解码器

该类是个抽象类,不可直接使用

它会将上一站传过来的ByteBuf中的数据进行解码,解码出一个List,然后迭代List 列表
逐个将Java POJO对象传入下一个Inbound入站处理器,

12、Decoder解码器和Encoder编码器_第1张图片

其中解码的方法 decoder是个抽象方法,由子类实现。

decoder–>ReplayingDecoder类

ReplayingDecoder 类是ByteToMessageDecoder的子类,作用:

  • 在读取ByteBuf缓冲区的数据之前,需要检查缓冲区中是否有足够的字节
  • 若ByteBuf中有足够的字节,则会正常读取,如果没有足够的字节,则会停止解码,会留着数据,等待下一次IO事件再读取。

ReplayingDecoder分包解码器:
在netty中进行字符串的传输,可以采用普通的Header-Content内容传输协议:

  • Header 部分放置字符串的长度,用int来描述

  • content部分用来放置字符串。
    在实际的传输过程中,一个Header-content内容包,在发送端会被编码成为一个ByteBuf内容发送包,
    当到达接收端后,可能被分成很多ByteBuf接收包,对于这个参差不齐的接收包,该解码器操作:

  • 1:解码出这个字符串的长度

  • 2:校验ByteBuf缓冲区的字节长度等于头部的解析的字符串长度,才会读取ByteBuf缓冲区的字节。

不适用场景:
在数据解析逻辑复杂的应用场景,ReplayingDecoder在解析速度上相对较差
原因:在ByteBuf中的长度不够时,ReplayingDecoder会抛出一个ReplayError异常,这时,会把ByteBuf中的
读指针还原到之前所在的位置。然后等待下一次IO事件,再继续解析。这对CPU是一个较大的负担。

decoder–>MessageToMessageDecoder:

12、Decoder解码器和Encoder编码器_第2张图片
在上图中,出站类型是Object,那么在下一个Inbound节点的入站类型,就是Object,这时,就需要用到MessageToMessageDecoder,
入参需要明确。

netty开箱即用的内置解码器:

  • FixedLengthFrameDecoder(固定长度数据包解码器):
    适用场景:每个数据包的长度都是固定的,例如:100个字节。
    只要把这个解码器加入到流水线中,就会把入站的ByteBuf包解析成一个个长度为100的数据包,然后进入下个Inbound节点

  • LineBaseFrameDecoder(行分割数据包解码器):
    适用场景:每个ByteBuf数据包,适用换行符(或者回车换行符)作为数据包的边界分隔符。

  • DelimiterBaseFrameDecoder(自定义分隔符数据包解码器):可以自定义分隔符。

  • LengthFieldBaseFrameDecoder(自定义长度数据包解码器):可以自定义长度(最为复杂)

Encoder:

Encoder是将Java POJO对象转化成最终的ByteBuf二进制类型。通过流水线写入到低层的Java通道。
在netty中,编码器是一个Outbound出站处理器。
编码器是将上一站输入的数据进行编码或者格式转化,传递到下一个ChannelOutBoundHander出站处理器

Encode 有MessageToByteEncoder编码器接口和MessageToMessageEncoder编码器接口

总结

在一个channelPipeline中有N个handler节点,每一个Hander都有入站(Inbound)和出站(Outbound) 出站操作
所以Decoder和Encoder是在相互配合使用的。

前面的都是Decoder和Encoder分开实现的。Netty通过继承ByteToMessageDecoder和MessageToByteEncoder或子类,
生成了一个新类型:Codec类型。同时具备解码和编码功能。

ByteToMessageCodec(继承方式):通过继承,将解码和编码结合,将前面的decoder和encoder方法放在同一个自定义类中。
本来放入channelPipeline中需要添加2个节点,现在添加1个节点即可。

CombinedChannelDuplexHander组合器(通过组合的方式):将编码器和解码器的所有的逻辑强制性的放在同一个类中,
在只需要编码和解码的流水线上,逻辑太臃肿,不大合适。这里将解码器和编码器结合起来使用,捆绑使用,更加的灵活。

你可能感兴趣的:(netty)