ProtocolCodec discussion has been edited by Emmanuel Lécharny (Nov 11, 2008).

Change summary:

Added some doc about the events

(View changes)

Content:

Introduction

This filter is one of the most important one. In many case, writing a MINA based application without having such a filter added is not really meaningful.

Events handled

Here is a list of all the handled events in this filter :

event Handled Description
exceptionCaught N/A
filterClose N/A
filterSetTrafficMask Will be removed
filterWrite  
onPostRemove Invoked when the filter is removed from the chain
onPreAdd Invoked when this filter is added to the chain
sessionOpened Useless. May be removed
messageReceived A message has been read and need to be decoded
messageSent ???
sessionClosed An event received when the session has been closed
sessionCreated An event received when a new session has been created
sessionIdle N/A

Description

Constructor

In order to be able to encode or decode a message, we need to pass the filter a factory, which will be used to create those two parts of the codec :

  • an encoder
  • a decoder

The factory is pretty simple. It offers two methods :

public interface ProtocolCodecFactory {
    /**
     * Returns a new (or reusable) instance of [EMAIL PROTECTED] ProtocolEncoder} which
     * encodes message objects into binary or protocol-specific data.
     */
    ProtocolEncoder getEncoder(IoSession session) throws Exception;

    /**
     * Returns a new (or reusable) instance of [EMAIL PROTECTED] ProtocolDecoder} which
     * decodes binary or protocol-specific data into message objects.
     */
    ProtocolDecoder getDecoder(IoSession session) throws Exception;
}

We can see that those two methods have a single parameter, an IoSession, which is a bad idea. A codec should not depend on a session. In fact, not a single codec uses this session, and I think that it should be removed.

Moreover, it forces the encoded and decoder instances to be created only when the first message is received, which can be a hassle, as ithe encoder/decoder creation has to be synchronized. It would be way better to create those instances when the filter is created.

It's also possible to pass the encoder and decoder directly, as a factory will be created internally to encapsulate those two methods.

SessionCreated event

The current handling for this event is pretty simple : it stores the Encoder and Decoder instances in the session attributes.

public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
        // Creates the decoder and stores it into the newly created session
        session.setAttribute(DECODER, factory.getDecoder(session));

        // Creates the encoder and stores it into the newly created session
        session.setAttribute(ENCODER, factory.getEncoder(session));

        // Call the next filter
        nextFilter.sessionCreated(session);
    }

The encoder and decoder are stateless, we don't need to pass a session object to the getEncoder/Decoder() methods.

 
 Thre is another problem : if we add this codec in the chain after the session has been created, then the encoder and decoder are never added into the session attributes, which is bad. This is addressed in
https://issues.apache.org/jira/browse/DIRMINA-635

SessionClosed event

 This event is received when the session is closed. We have to remove the Encoder and Decoder instances from the session's attributes, and to dispose those elements. As we may have remaining messages to decode, we have to process them first.

 We have different cases, as of MINA 2.0.0-M3 :

  1. We don't have anymore bytes in the incoming request : just close everything
  2. We have some more bytes, and we can decode a full message out of them : decode the message, and go back to step (1)
  3. We have some more bytes, but we can't decode a full message out of them :throw an exception

 I'm not sure that we should decode anything when we receive a sessionClosed message : The session is already closed, and any other treatment may violate the client's will.

OnPreAdd

This event is received when we try to insert this filter during a session. What it does is very simple :

- Checks that the filter is not already present in the chain. If so, generates an exception

- Initialize the encoder and decoder.

Nothing much to tell about this simple handler

OnPostRemove

This event is received when this filter is removed from the chain. We simply :

  • removes the encoder, decoder and callback from the session's attributes
  • dispose thos three instances

Nothing much to tell about this simple handler

MessageReceived event

Reply via email to