users@grizzly.java.net

Re: cutting up logical sets of bytes from data stream? (in 2.0)

From: Emit Sorrels <emit.sorrels_at_gmail.com>
Date: Wed, 17 Dec 2008 10:16:03 -0500

On Wed, Dec 17, 2008 at 10:07:30AM +0100, John ROM wrote:
> Hi Emit,
>
> >
> > Thanks to Alex's earlier suggestions I got a sort of working grizzly2
> > based implementation of my protocol... then I tried mina 2 and was
> > shocked that all the plumbing was in place. I cooked up a decoder
> > based on their standard CumulativeProtocolDecoder and had it
> > working in a few minutes...
> I find your this very interresting...
> You got me curious.
> if its not to much work for you,
> would it be possible to share your mina 2 and grizzly 2 implementation code.
> Pseudo would also be ok
>
> Many Greetings John
>

Here's the mina based decoder which is basically a copy of the
second ImageResponseDecoder example from
http://mina.apache.org/tutorial-on-protocolcodecfilter.html
As for the grizzly analog, I'm sure you can write a better one...
mine's just very similar to this, except there I need to do my own
buffering&chopping.

// I'm using mina 2.0.0-M4
public class FooMessageDecoder extends CumulativeProtocolDecoder {
    private static final String DECODER_MESSAGE = "FOOBAR";
    private static final int MAX_DATA_SIZE = 4000;

    // I don't think we really need this extra class,
    // I'm just following the template from the tutorial..
    private static class DecoderState {
        BaseMessage msg;
    }

    @Override
    protected boolean doDecode(IoSession session, IoBuffer in,
            ProtocolDecoderOutput out) throws Exception {
        // not sure what the deal is with this decoder state stuff,
        // or if there are any race conditions possible from the following
        DecoderState decoderState = (DecoderState) session.getAttribute(DECODER_MESSAGE);
        if (decoderState == null) {
            decoderState = new DecoderState();
            session.setAttribute(DECODER_MESSAGE, decoderState);
        }
        if (decoderState.msg == null) {
            // leading word == size of data
            boolean tmp = in.prefixedDataAvailable(2, MAX_DATA_SIZE);
            if (tmp) {
                //createMessage(in) reads next 2+ bytes, figures out what
                //type of message it is, creates a message object of that
                //corresponding class (which all extend BaseMessage)
                decoderState.setMessage(MessageFactory.createMessage(in));
                //message object is directly sent to IoHandlerAdapter's
                //messageReceived(IoSession,Object msg) which can add it to
                //a processing queue, etc.
                out.write(decoderState.msg);
                session.removeAttribute(DECODER_MESSAGE);
            } else {
                return false;
            }
        }
        return true;
    }
}