我们说一下编码和解码,或者数据从一种特定协议的格式到另一个格式的转换,交给编解码器的组件来处理,Netty提供了多种组件,简化了支持广泛的协议而创建自定义的编解码器的过程

我们定义如何解析在两个节点之间来回传输的原始字节,以及如何将其和目标应用程序的数据格式进行互相转换,这种转换逻辑由编解码器处理,编解码器由编码器和解码器组成

什么是编解码器

编码器可以将消息转换为适合于传输的格式,例如字节流,解码器则是将网络字节流转换回应用程序的消息格式

我们将会说两种常见的编解码器类

分别是将字节解码为消息 — ByteToMessageDecoder 和 ReplayingDecoder

将一种消息类型解码为另一种 — MessageToMessageDecoder

在我们需要为ChannelPipeline的下一个ChannelInboundHandler转换入站的数据时候可讷讷个用到

基础抽象类ByteToMessageDecoder

字节解码为消息是一种常见的任务,Netty提供了基类ByteToMessageDecoder,这个类会对入站的数据进行缓冲,直到准备好处理

图片

我们接受了一个包含了int的字节流,每个int需要单独的处理,这时候,解析这个字节流,就需要扩展ByteToMessageDecoder类

我们每次从ByteBuf中读取4个字节,然后解码为一个int,然后加到List中,当没有更多的元素可以加入的时候,进行放行

图片

代码如下:

图片

我们只需要校验一下剩余数据是否足够满足一个int,就可以进行解码了

然后是抽象类 ReplayingDecoder

扩展了ByteToMessageDecoder,自定义了一个ByteBuf实现

ReplayingDecoderByteByf,

<S>指定了decode返回的类型

图片

扩展的解码器代码如下

图片

从byte提取的int会被加到List中,如果没有足够的字节可以用,readInt将会抛出一个异常,等待有足够的数据可以供读取的时候,decode会被再次调用

但是实际上ReplayingDecoder会稍慢于ByteToMessageDecoder

所以还是经常使用ByteToMessageDecoder

然后是MessageToMessageDecoder

下面的抽象基类在两个消息格式之间进行转换

类型I指定了decode()方法的输入参数msg的类型,这是必须要实现的方法

图片

对应的decode 方法的API如下

图片

我们编写一个从Integer转换为String的解码器来扩展MessageToMessageDecoder<Integer>,其decode会将Integer转换为String

解码的流程如下

图片

图片 图片

然后是TooLongFrameException类

Netty是一个异步框架,所以需要在字节可以再解码之前进行缓存,为了避免缓存过多的数据耗尽可用的内存,提供了该异常,避免解码器在超过指定的大小限制的时候抛出

如何处理这个异常完全取决于用户,某些协议可能返回特殊的响应

我们看一下如何抛出这个异常

图片

编码器

解码器对应的就是编码器,编码器实现了ChannelOutboundHandler

我们尝试编写一些编码器

将消息编码为字节

将消息编码为消息

基础的抽象基类MessageToByteEncoder

一种逆向的操作

将消息进行编码为字节

<I>的泛型是创建MessageToByteEncoder的时候的声明的

图片

这个类相比解码器少了一个方法,因为在Channel关闭后产生消息并没有什么意义

我们下面展示的ShortToByteEncoder,其接受一个Short类型的实例为消息,编码为原子类型值,并进行写入ByteBuf中,随后交给下一个 ChannelOutboundHandler

代码如下

图片

抽象类MessageToMessageEncoder

用于不同类型的消息的转换

对于这个抽象类,我们只需要实现一个encode()方法

图片

我们实现了一个IntegerToStringEncoder 扩展了 MessageToMessageEncoder

图片

抽象的编解码器类 ByteToMessageCodec

我们要将字节解码为某种消息,然后再次进行编码,ByteToMessageCodec可以处理这个,结合了ByteToMessageDecoder和逆向 MessageToByteEncoder

常见的ByteToMessageCodec API如下

图片

然后是MessageToMessageCodec

我们看到了Encoder以一种消息格式变为了另一种的消息的格式

我们可以利用MessageToMessageCodec,帮助其在单个类中实现转换的往返过程

主要的API方法有:

图片

方便我们在不同的消息API中来回转换数据

代码如下

图片

图片

发表评论

邮箱地址不会被公开。 必填项已用*标注