《netty权威指南》私有协议栈开发:主要是书上写的不太全,而且有些地方要用到前几章学得东西,所以这里直接把一些书上的编解码粘贴出来
书上用到JBoss的marshalling进行编解码,所以首先要添加marshalling的依赖
org.jboss.marshalling
jboss-marshalling-serial
2.0.0.Beta2
在编解码前还有一个地方要注意一下,就是在client和server中书上有个坑
ch.pipeline().addLast(new NettyMessageDecoder(1024 * 1024, 4, 4, -8, 0));
简单介绍一下:第一个参数是指数据包的最大值,第二个是协议中“长度”字段的偏移地址,第三个是“长度字段”的长度,第四个是针对2和3的一个容量修正,因为源码里面会会把参数2和3加起来,会使frameLength过大而抛异常
(1)frameLength就是协议可读范围的窗口,值是当前消息包的字节数。
(2)lengthFieldEndOffset是“长度”字段的偏移量(因为这里在编解码的时候要同时把长度字段一起处理,所以要把调整长度)
由于netty包中关于marshalling的MarshallingDecode和MarshallingEncoder不知道什么原因变得protected了,所以要扩展成public
(编解码其实是用于协议的attachment字段,也就是附加数据)
public class NettyMarshallingDecoder extends MarshallingDecoder{
public NettyMarshallingDecoder(UnmarshallerProvider provider) {
super(provider);
}
public NettyMarshallingDecoder(UnmarshallerProvider provider, int maxObjectSize) {
super(provider, maxObjectSize);
}
@Override
public Object decode(ChannelHandlerContext arg0, ByteBuf arg1)
throws Exception {
return super.decode(arg0, arg1);
}
}
public class NettyMarshallingEncoder extends MarshallingEncoder{
public NettyMarshallingEncoder(MarshallerProvider provider) {
super(provider);
}
@Override
public void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out)
throws Exception {
super.encode(ctx, msg, out);
}
}
使用工厂方法去创建编解码器
public class MarshallingCodeCFactory {
public static NettyMarshallingDecoder buildMarshallingDecoder() {
MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setVersion(5);
UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);
NettyMarshallingDecoder decoder = new NettyMarshallingDecoder(provider, 10240);
return decoder;
}
public static NettyMarshallingEncoder buildMarshallingEncoder() {
MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setVersion(5);
MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);
NettyMarshallingEncoder encoder = new NettyMarshallingEncoder(provider);
return encoder;
}
}