簡體   English   中英

使用 Kryo 序列化的 Netty 編碼器和解碼器

[英]Netty Encoder And Decoder using Kryo Serialization

我是 Netty 4.0.29 的新手,並嘗試使用 Kryo 作為序列化庫來制作自定義對象編碼器和對象解碼器,但我無法使其工作。 由於我是 Netty 的新手,也許這就是我搞砸的原因。 我正在使用MessageToMessageEncoderMessageToMessageDecoder

這是我的編碼器 -

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 真的很陌生,我可能做錯了什么,所以請告訴我。

我認為更好的是 ByteToMessageDecoder 和 MessageToByteEncoder。 不要忘記發送第一個長度的數據,否則您無法識別一個數據包的起點和終點。 有我的簡單例子:

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);

    }
}

和編碼器

public class KryoEncoder extends MessageToByteEncoder<Object> {

    private final Kryo kryo;

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

    @Override
    protected void encode(ChannelHandlerContext ctx, Object in, ByteBuf out) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        Output output = new Output(outStream, 4096);

        kryo.writeClassAndObject(output, in);
        output.flush();

        byte[] outArray = outStream.toByteArray();
        out.writeShort(outArray.length);
        out.writeBytes(outArray);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM