使用Kryo序列化的Netty编码器和解码器

时间:2015-06-30 19:54:42

标签: java netty kryo

我是Netty 4.0.29的新手,并尝试使用Kryo作为序列化库来制作自定义对象编码器和对象解码器,但我无法使其工作。因为我是Netty的新手,也许这就是我弄乱一些东西的原因。我正在使用 MessageToMessageEncoder MessageToMessageDecoder

这是我的编码器 -

public class KryoEncoder extends  MessageToMessageEncoder<Object>{

    private Kryo kryo;
    private Output output;

    public KryoEncoder(Kryo kryo, int bufSize, int maxBufSize) {
        this.kryo = kryo;
        output = new Output(bufSize, maxBufSize);
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg,
            List<Object> out) throws Exception {
        output.clear();
        kryo.writeClassAndObject(output, msg);
        int total = output.position();
        out.add(Unpooled.wrappedBuffer(output.getBuffer(), 0 , total));
    }

}

这是解码器 -

public class KryoDecoder extends MessageToMessageDecoder<Object>{
    private Kryo kryo;
    private Input input;

    public KryoDecoder (Kryo kryo) {
        this.kryo = kryo;
        input = new Input();
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
        ByteBuf buffer = (ByteBuf)msg;
        byte[] ar = new byte[buffer.readableBytes()];
        buffer.readBytes(ar);
        input.read(ar, buffer.readerIndex(), buffer.readableBytes());
        Object object = kryo.readClassAndObject(input);
        buffer.readerIndex(input.position());
        out.add(object);
    }
}

这是抛出的异常的短堆栈,我知道它是一个空指针异常,在解码器的字节数组中有些错误但不确定是什么。

Caused by: java.lang.NullPointerException
    at java.lang.System.arraycopy(Native Method)
    at com.esotericsoftware.kryo.io.Input.read(Input.java:254)
    at TestWithKryo.KryoDecoder.decode(KryoDecoder.java:31)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89)
    ... 14 more

解码时发生异常,我在发送编码对象时检查了编码器并检查了channelFuture,但没有抛出任何异常。

再一次,因为我是netty的新手,所以我可能做错了所以请告诉我。

1 个答案:

答案 0 :(得分:1)

我认为更好的是ByteToMessageDecoder和MessageToByteEncoder。不要忘记发送第一长度的数据,或者您不能识别一个数据包的开始位置和另一个数据包的结束位置。有一个简单的例子:

// eg. here
@Override
void onCreate(Bundle state) {
    MakePOSTAsync task = new MakePOSTAsync() {
        @Override
        protected void onPostExecute(String  string){
            // Do whatever you need for this activity
        }
    }
    // etc.
}

和编码器

public class KryoDecoder extends ByteToMessageDecoder {

    private final Kryo kryo;

    public KryoDecoder(Kryo kryo) {
        this.kryo = kryo;
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {

        if (in.readableBytes() < 2)
            return;

        in.markReaderIndex();

        int len = in.readUnsignedShort();

        if (in.readableBytes() < len) {
            in.resetReaderIndex();
            return;
        }

        byte[] buf = new byte[len];
        in.readBytes(buf);
        Input input = new Input(buf);
        Object object = kryo.readClassAndObject(input);
        out.add(object);

    }
}