我们在开发中经常会把Java类进行implements Serializable用来网络传输的序列化和反序列化,过程其实就是将Java对象转编码为字节数组或者ByteBuffer对象进行传输,当远程服务读取到ByteBuffer对象或者字节数组时,需要将其解码为Java对象。这也就是编解码技术。
Java的序列化只是编解码技术中的一种,但是由于其1,不支持跨语言;2,序列化后的码流相对较大(Java.io.Serializable序列化相对于基于BuyeBuffer的二进制编码的码流大小大概为5:1);3,性能相对来说较差(Java序列化只有二进制编码的大概6%)。业界出现了很多编解码的框架,我们来看看我们选择一款编解码框架时需要考虑的东西:
1,是否支持跨语言,支持的语言种类是否丰富(现在跨系统、跨语言的交互太多了);
2,编码后的码流大小(码流越大,存储占空间、网络传输更占带宽、吞吐量越低);
3,编解码的性能;
4,类库是否小巧,API使用是否方便;
5,使用者需要手工开发的工作量和难度。
好,下边讲述三种业界比较流行,而且Netty支持,通过Netty编程来实现的编解码框架;
一,MessagePack编解码:MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.(官方解释)。它具有a,编解码高效、性能高;b,序列化之后码流小;c,支持跨语言(Java、Python、Ruby、C#、Lua、Go、C、C++……)
好,看下MessagePack编解码的几个重要点:1,利用MessagePack实现编码和解码的ChannelHandlerAdapter;2,server和client端,initChannel时将编解码ChannelHandler添加到pipeline;3,支持粘包半包操作:LengthFieldBasedFrameDecoder、LengthFieldPrepender的加入。重点代码如下:
/**
* @author liujiahan
* @Title: MsgpackDecoder
* @Copyright: Copyright (c) 2018
* @Description: 利用MessagePack解码 MessageToMessageDecoder<I> extends ChannelHandlerAdapter
* @Created on 2018/10/24
* @ModifiedBy:
*/
public class MsgpackDecoder extends MessageToMessageDecoder<ByteBuf> {
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
final byte[] array;
final int length = byteBuf.readableBytes();
array = new byte[length];
byteBuf.getBytes(byteBuf.readerIndex(),array,0,length);
MessagePack messagePack = new MessagePack();
list.add(messagePack.read(array));
}
}
/**
* @author liujiahan
* @Title: MsgpackEncoder
* @Copyright: Copyright (c) 2018
* @Description: 利用MessagePack编码 MessageToByteEncoder<I> extends ChannelHandlerAdapter
* @