You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "Fernando C. de Castro" <fe...@altriz.com.br> on 2007/01/24 23:21:55 UTC

Changing Codec "on the fly" ?

Hello,

   I am trying to do something that I don't even know is possible. Can I change the codec "on the fly"?


Let me try and explain what I'm doing so you guys can follow my thoughts.

On my SessionHandler (extends IoHandlerAdapter) I add a Codec to the session as it's created:

public void sessionCreated( IoSession session )
    {
    	

	     session.getFilterChain().clear();
	
		
 		session.getFilterChain().addFirst  (
				"idcodec",
				new ProtocolCodecFilter(new IDprotocolCodecFactory()));

    }


OK, so it loads my IDprotocolCodecFactory which has one messageEncoder and one messageDecoder:

public class IDprotocolCodecFactory extends DemuxingProtocolCodecFactory 
{
	public IDprotocolCodecFactory () {
		super.register(IDmessageDecoder.class);
		super.register(IDmessageEncoder.class);
	}
}


This messageDecoder waits for 2 bytes, analyses them then returns MessageDecoderResult.OK , and that fires the messageReceived() on my SessionHanlder. So far, working as expected.

Then, I would like to change the Codec (e.g. the "identification stage" is over, now the server expects another kind of messages). So, on the messageReceived(), I try to change the codec:


   public void messageReceived( IoSession session, Object message )
    {
    	
    	if (session.getFilterChain().contains("idcodec")){

    		       	session.getFilterChain().remove("idcodec");	
	       		session.getFilterChain().addFirst  (
					"messagecodec",
					new ProtocolCodecFilter(new MyMessageCodecFactory()));

    	}

       else {

       // after the "idcodec" was removed from the chain and "messagecodec" was placed instead,
       // messageReceived() will be triggered by "messagecodec" and will always get to this 'else'.

      // (or so I expect...)
       }
    	
   }

The MyMessageCodecFactory class is similar the presented IDprotocolCodecFactory (extends DemuxingProtocolCodecFactory )

    Is it possible to change the codec like this? Because it's not working. It's like I'm stuck with "idcodec" forever, it never changes to "messagecodec".

    Any help and/or explanation is appreciated.



Fernando




Changing Codec "on the fly" ? (cont'd)

Posted by "Fernando C. de Castro" <fe...@altriz.com.br>.
I forgot to mention I am using MINA 1.0.1

Re: Changing Codec "on the fly"?

Posted by "Fernando C. de Castro" <fe...@altriz.com.br>.
Thank you, Trustin. There actually is a contract between my server and their remote peers that they shoud shut up while the server switches codecs (they can start talking again after they receive a specific message giving notice of the switch), so I wasn't even considering other circumstances. Lack of vision. :P

I will be waiting for a thread-safe "replace" method, to come with MINA 2.0. Meanwhile, I changed my codec a bit to deal with both types of messages. You suggested a codec that delegates to two child codecs appropriately. How exactly could I implement that?

Thanks.


Fernando


 Sat, 27 Jan 2007 23:56:05 +0900, "Trustin Lee" <tr...@gmail.com> escreveu:

> 
> Hi Fernando,
> 
> On 1/25/07, Fernando C. de Castro <fe...@altriz.com.br> wrote:
> >
> >
> > Hello,
> >
> >    I am trying to do something that I don't even know is possible. Can I
> > change the codec "on the fly"?
> >
> >
> > Let me try and explain what I'm doing so you guys can follow my thoughts.
> >
> > On my SessionHandler (extends IoHandlerAdapter) I add a Codec to the
> > session as it's created:
> >
> > public void sessionCreated( IoSession session )
> >     {
> >
> >
> >              session.getFilterChain().clear();
> >
> >
> >                 session.getFilterChain().addFirst  (
> >                                 "idcodec",
> >                                 new ProtocolCodecFilter(new
> > IDprotocolCodecFactory()));
> >
> >     }
> >
> >
> > OK, so it loads my IDprotocolCodecFactory which has one messageEncoder and
> > one messageDecoder:
> >
> > public class IDprotocolCodecFactory extends DemuxingProtocolCodecFactory
> > {
> >         public IDprotocolCodecFactory () {
> >                 super.register(IDmessageDecoder.class);
> >                 super.register(IDmessageEncoder.class);
> >         }
> > }
> >
> >
> > This messageDecoder waits for 2 bytes, analyses them then returns
> > MessageDecoderResult.OK , and that fires the messageReceived() on my
> > SessionHanlder. So far, working as expected.
> >
> > Then, I would like to change the Codec (e.g. the "identification stage" is
> > over, now the server expects another kind of messages). So, on the
> > messageReceived(), I try to change the codec:
> >
> >
> >    public void messageReceived( IoSession session, Object message )
> >     {
> >
> >         if (session.getFilterChain().contains("idcodec")){
> >
> >                         session.getFilterChain().remove("idcodec");
> >                         session.getFilterChain().addFirst  (
> >                                         "messagecodec",
> >                                         new ProtocolCodecFilter(new
> > MyMessageCodecFactory()));
> >
> >         }
> >
> >        else {
> >
> >        // after the "idcodec" was removed from the chain and
> > "messagecodec" was placed instead,
> >        // messageReceived() will be triggered by "messagecodec" and will
> > always get to this 'else'.
> >
> >       // (or so I expect...)
> >        }
> >
> >    }
> >
> > The MyMessageCodecFactory class is similar the presented
> > IDprotocolCodecFactory (extends DemuxingProtocolCodecFactory )
> >
> >     Is it possible to change the codec like this? Because it's not
> > working. It's like I'm stuck with "idcodec" forever, it never changes to
> > "messagecodec".
> 
> 
> You can if there's a contract between you and your remote peer that the
> remote peer doesn't send any message while you switch your codec.  If not,
> the idcodec can receive unwanted data, or data will be received when no
> codec is in action.
> 
> You can work around this problem by creating a codec that delegates to the
> two child codecs appropriately.  Of course, we will introduce an easier way
> to replace the codec on the fly like this in 2.0:
> 
> session.getFilterChain().replace("codec", newCodec);
> 
> HTH,
> Trustin
> -- 
> what we call human nature is actually human habit
> --
> http://gleamynode.net/
> --
> PGP key fingerprints:
> * E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
> * B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6
> 
> 

Re: Changing Codec "on the fly" ?

Posted by Trustin Lee <tr...@gmail.com>.
On 1/27/07, Trustin Lee <tr...@gmail.com> wrote:
>
> Hi Fernando,
>
> On 1/25/07, Fernando C. de Castro <fe...@altriz.com.br> wrote:
> >
> >
> > Hello,
> >
> >    I am trying to do something that I don't even know is possible. Can I
> > change the codec "on the fly"?
> >
> >
> > Let me try and explain what I'm doing so you guys can follow my
> > thoughts.
> >
> > On my SessionHandler (extends IoHandlerAdapter) I add a Codec to the
> > session as it's created:
> >
> > public void sessionCreated( IoSession session )
> >     {
> >
> >
> >              session.getFilterChain().clear();
> >
> >
> >                 session.getFilterChain().addFirst  (
> >                                 "idcodec",
> >                                 new ProtocolCodecFilter(new
> > IDprotocolCodecFactory()));
> >
> >     }
> >
> >
> > OK, so it loads my IDprotocolCodecFactory which has one messageEncoder
> > and one messageDecoder:
> >
> > public class IDprotocolCodecFactory extends DemuxingProtocolCodecFactory
> > {
> >         public IDprotocolCodecFactory () {
> >                 super.register(IDmessageDecoder.class);
> >                 super.register(IDmessageEncoder.class);
> >         }
> > }
> >
> >
> > This messageDecoder waits for 2 bytes, analyses them then returns
> > MessageDecoderResult.OK , and that fires the messageReceived() on my
> > SessionHanlder. So far, working as expected.
> >
> > Then, I would like to change the Codec (e.g. the "identification stage"
> > is over, now the server expects another kind of messages). So, on the
> > messageReceived(), I try to change the codec:
> >
> >
> >    public void messageReceived( IoSession session, Object message )
> >     {
> >
> >         if (session.getFilterChain().contains("idcodec")){
> >
> >                         session.getFilterChain().remove("idcodec");
> >                         session.getFilterChain().addFirst  (
> >                                         "messagecodec",
> >                                         new ProtocolCodecFilter(new
> > MyMessageCodecFactory()));
> >
> >         }
> >
> >        else {
> >
> >        // after the "idcodec" was removed from the chain and
> > "messagecodec" was placed instead,
> >        // messageReceived() will be triggered by "messagecodec" and will
> > always get to this 'else'.
> >
> >       // (or so I expect...)
> >        }
> >
> >    }
> >
> > The MyMessageCodecFactory class is similar the presented
> > IDprotocolCodecFactory (extends DemuxingProtocolCodecFactory )
> >
> >     Is it possible to change the codec like this? Because it's not
> > working. It's like I'm stuck with "idcodec" forever, it never changes to
> > "messagecodec".
>
>
> You can if there's a contract between you and your remote peer that the
> remote peer doesn't send any message while you switch your codec.  If not,
> the idcodec can receive unwanted data, or data will be received when no
> codec is in action.
>
> You can work around this problem by creating a codec that delegates to the
> two child codecs appropriately.  Of course, we will introduce an easier way
> to replace the codec on the fly like this in 2.0:
>
> session.getFilterChain ().replace("codec", newCodec);
>

I filed an issue for this problem:

https://issues.apache.org/jira/browse/DIRMINA-339

You can track it by 'watching' the issue.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Changing Codec "on the fly" ?

Posted by Trustin Lee <tr...@gmail.com>.
Hi Fernando,

On 1/25/07, Fernando C. de Castro <fe...@altriz.com.br> wrote:
>
>
> Hello,
>
>    I am trying to do something that I don't even know is possible. Can I
> change the codec "on the fly"?
>
>
> Let me try and explain what I'm doing so you guys can follow my thoughts.
>
> On my SessionHandler (extends IoHandlerAdapter) I add a Codec to the
> session as it's created:
>
> public void sessionCreated( IoSession session )
>     {
>
>
>              session.getFilterChain().clear();
>
>
>                 session.getFilterChain().addFirst  (
>                                 "idcodec",
>                                 new ProtocolCodecFilter(new
> IDprotocolCodecFactory()));
>
>     }
>
>
> OK, so it loads my IDprotocolCodecFactory which has one messageEncoder and
> one messageDecoder:
>
> public class IDprotocolCodecFactory extends DemuxingProtocolCodecFactory
> {
>         public IDprotocolCodecFactory () {
>                 super.register(IDmessageDecoder.class);
>                 super.register(IDmessageEncoder.class);
>         }
> }
>
>
> This messageDecoder waits for 2 bytes, analyses them then returns
> MessageDecoderResult.OK , and that fires the messageReceived() on my
> SessionHanlder. So far, working as expected.
>
> Then, I would like to change the Codec (e.g. the "identification stage" is
> over, now the server expects another kind of messages). So, on the
> messageReceived(), I try to change the codec:
>
>
>    public void messageReceived( IoSession session, Object message )
>     {
>
>         if (session.getFilterChain().contains("idcodec")){
>
>                         session.getFilterChain().remove("idcodec");
>                         session.getFilterChain().addFirst  (
>                                         "messagecodec",
>                                         new ProtocolCodecFilter(new
> MyMessageCodecFactory()));
>
>         }
>
>        else {
>
>        // after the "idcodec" was removed from the chain and
> "messagecodec" was placed instead,
>        // messageReceived() will be triggered by "messagecodec" and will
> always get to this 'else'.
>
>       // (or so I expect...)
>        }
>
>    }
>
> The MyMessageCodecFactory class is similar the presented
> IDprotocolCodecFactory (extends DemuxingProtocolCodecFactory )
>
>     Is it possible to change the codec like this? Because it's not
> working. It's like I'm stuck with "idcodec" forever, it never changes to
> "messagecodec".


You can if there's a contract between you and your remote peer that the
remote peer doesn't send any message while you switch your codec.  If not,
the idcodec can receive unwanted data, or data will be received when no
codec is in action.

You can work around this problem by creating a codec that delegates to the
two child codecs appropriately.  Of course, we will introduce an easier way
to replace the codec on the fly like this in 2.0:

session.getFilterChain().replace("codec", newCodec);

HTH,
Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6