当前位置: 首页 > 后端技术 > Java

Netty系列:自定义编解码器介绍

时间:2023-04-01 18:51:25 Java

在之前的netty系列文章中,我们讲了如何将对象或String转换为ByteBuf。通过使用netty自带的encoder和decoder,我们可以很方便的实现对象和ByteBuf之间的转换,然后就可以随意的往channel中写入对象和字符串了。使用netty自带的encoder当然好,但是如果你有一些特殊的需求,比如在编码过程中想对数据进行变换,或者选择对象的字段,那么你可能需要自定义编解码器。自定义编码器自定义编码器需要继承MessageToByteEncoder类,并实现encode方法,在该方法中编写具体的编码逻辑。在这个例子中,我们要计算2的N次方。据说一张纸折叠100次可以达到地球到月球的高度。这么大的数据,不是一个普通号就能容纳的。我们将使用BigInteger来处理保存这个巨大的数字。那么对于encoder来说,需要将这个BigInteger转换成byte数组。同时,在读取字节数组的过程中,我们需要定义哪些字节数据属于同一个BigInteger,这就需要对写入的数据格式进行约定。这里我们使用一个三部分的数据结构来表示一个BigInteger。第一部分是魔字,即魔字。这里我们使用神奇的词“N”。当读取这个魔法字时,就意味着下一个数字是一个BigInteger。第二部分是表示bigInteger数字的字节数组的长度。得到这个长度值后,就可以读取所有的字节数组值,最后转换成BigInteger。因为BigInteger是Number的子类,为了泛化编码器,我们使用Number作为MessageToByteEncoder的泛型。核心编码代码如下:protectedvoidencode(ChannelHandlerContextctx,Numbermsg,ByteBufout){//将number编码到ByteBufBigIntegerv;if(msginstanceofBigInteger){v=(BigInteger)msg??;}else{v=newBigInteger(String.valueOf(msg));}//将BigInteger转换为byte[]数组byte[]data=v.toByteArray();intdataLength=data.length;//编码数字out.writeByte((byte)'N');//魔法字out.writeInt(dataLength);//数组长度out.writeBytes(data);//Thefinaldata}自定义解码器有编码后的字节数组,可以在解码器中解码。上一节介绍过,编码后的数据格式为魔字N+数组长度+真实数据。其中,魔字长度为1个字节,数组长度为4个字节,前面部分一共5个字节。所以解码时首先判断ByteBuf中可读字节的长度是否小于5,小于5则数据无效,可直接返回。如果可读字节长度大于5,说明数据有效,可以解码数据。在解码过程中需要注意的是,并不是所有的数据都是我们期望的格式。如果我们在读取的过程中读到了一个我们不知道的格式,那就说明这个数据不是我们想要的,你可以交给其他的handler来处理。但是对于ByteBuf来说,一旦调用了read方法,reader索引的位置就会移动,所以在真正读取数据之前需要调用ByteBuf的markReaderIndex方法记录readerIndex。然后分别读取魔字、数组长度和剩余数据,最后将数据转换成BigInteger,如下图:protectedvoiddecode(ChannelHandlerContextctx,ByteBufin,Listout){//保证魔术字和数组的长度有效if(in.readableBytes()<5){return;}in.markReaderIndex();//检查魔法字intmagicNumber=in.readUnsignedByte();如果(magicNumber!='N'){in.resetReaderIndex();thrownewCorruptedFrameException("无效的魔法词:"+magicNumber);}//读取所有数据intdataLength=in.readInt();如果(in.readableBytes(){booleanoffered=answer.offer(msg);assertoffered;});}}小结本文实现了一个Number的编解码器,其实你可以自定义任何对象的编解码器。本文示例可参考:learn-netty4本文已收录于http://www.flydean.com/13-netty-customprotocol/最流行的解读,最深刻的干货,最简洁的教程,很多你不知道的小技巧等你来发现!欢迎关注我的公众号:《程序那些事儿》,懂技术,更懂你!

最新推荐
猜你喜欢