Billy Ryan
Billy Ryan

Reputation: 53

Multiple messages contained in one netty buffer issue

I've built a login server for a game client using the netty networking library.
This game client likes to send multiple packets in a single buffer, which poses an issue; that issue being the fact that in a netty decoding class, it can only return one message.

Then it is impossible for me to read multiple packets into multiple messages and return them in one decoding method call.

My question is: How should I best go about receiving multiple packets in one DecoderClass.decode() method call? Since I can only return one object, I am perplexed.

My preliminary decoding class is below:

protected Object decode(ChannelHandlerContext ctx, Channel c, ChannelBuffer buf,           
    VoidEnum state) throws Exception {
    short length = -1;
    short opcode = -1;
    short security = -1;

    while(buf.readableBytes() != 0 ){
        length = buf.readShort();
        opcode = buf.readShort();
        security = buf.readShort();
    }

    System.out.println("---------------------------------------");
    System.out.println("receivedLength: " + length);
    System.out.println("receivedOPCode: " + opcode);
    System.out.println("receivedSecurity: " + security);
    System.out.println("---------------------------------------");

    MessageCodec<?> codec = CodecLookupService.find(opcode);
    if (codec == null) {
        throw new IOException("Unknown op code: " + opcode + " (previous opcode: " + previousOpcode + ").");
    }


    previousOpcode = opcode;


    return codec.decode(buf);

My full github repository is here: https://github.com/desmin88/LoginServer

I hope I have provided enough information so someone can adequately understand my issue

Thanks,

Billy

Upvotes: 4

Views: 1740

Answers (1)

Sean Bright
Sean Bright

Reputation: 120644

You'll want to use a FrameDecoder to split up the received data into multiple "frames" to pass to your decoder. There is some example code in the API reference for FrameDecoder.

Rather than commenting more, you would do something like this:

  1. Implement your own FrameDecoder or use one of the existing ones. Let's say you implement your own MyGameFrameDecoder. If you write your own I recommend checking out the ReplayingDecoder (it's bad-ass).
  2. Add MyGameFrameDecoder to the ChannelPipeline on the server side, along with your existing decoder (DecoderClass).

Which would look something like this:

/* ... stuff ... */
pipeline.addLast("framer", new MyGameFrameDecoder());
pipeline.addLast("decoder", new DecoderClass());
/* ... more stuff ... */

Then the incoming data would go through the FrameDecoder and break up the stream into "frames" which will then be sent into your decoder which can just handle converting the data into an object that you can operate on.

Upvotes: 5

Related Questions