Limnic
Limnic

Reputation: 1866

Netty - Correct usage of a decoder

I have once again a question about Netty.

My scenario is:

incoming message (TCP) = header[byte,int,byte] body[bytes]

I have a packet class which holds the header & body with some methods. My channel pipeline is:

ProtocolDecoder > SessionHandler

My idea of the ProtocolDecoder is that it receives a message, splits it up and creates a Packet variable to pass on to the next handler in the pipeline.

The code of the ProtocolDecoder class:

public class ProtocolDecoder extends ByteToMessageDecoder {

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

    int opCode;
    int length;
    boolean encrypt;

    if (in.readableBytes() < 6) {
        return;
    }

    if (out.size() != 1) {
        Packet pa = new Packet();
        opCode = in.readByte();
        length = in.readInt();
        encrypt = in.readByte() == 1;
        pa.setOpcode(opCode);
        pa.setEncrypted(encrypt);
        pa.setLength(length);
        out.add(pa);
        in.discardReadBytes();
    }

    Packet p = (Packet) out.get(0);

    if (in.readableBytes() >= p.getLength()) {
        p.setPayload(in.copy());
    }
    }

}

The SessionHandler has this code:

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
Packet p = (Packet) msg;
System.out.println("Packet: " + p.toString());
}

So my two questions are:

UPDATE:

I remade the decoder like supposed to and this is my outcome: http://pastebin.com/wQz2LbYT

I wasn't sure if I had to put the code here because this post would become pretty big. Anyways it seems to work fine now :) thanks alot!

Upvotes: 2

Views: 3778

Answers (1)

Norman Maurer
Norman Maurer

Reputation: 23557

You don't use the ByteToMessageDecoder correctly as once you add something to the List (out) it will be removed once the method returns and forwarded to the next ChannelInboundHandler in the ChannelPipeline. If you need to hold a reference to your packet until you add it to out use a field in the class for it.

You can only access the array() if hasArray() returns true. Otherwise the buffer itself is backed by native memory. In this case you will need to use one of its getBytes(...) methods to copy the content to an array. That said if you only want to get the content of the buffer as string you can use ByteBuf.toString(Charset) for this.

Upvotes: 4

Related Questions