users@grizzly.java.net

RE: Re: [Q] How-to client Protocol

From: Simon Trudeau <strudeau_at_bluetreewireless.com>
Date: Fri, 29 Feb 2008 17:35:31 -0500

Of course it sounds french, I'm from Montreal! :.)

Your tutorial on SIP

http://weblogs.java.net/blog/jfarcand/archive/2008/02/writing_a_tcpud_1.
html

and the one from Erick

http://www.nabble.com/Grizzly-on-the-client-side%2C-a-modest-tutorial-td
15643977.html

were real breakthrough for me, they gave me the starting point I needed
to understand Grizzly better. By the way, I am still anxiously waiting
to the follow up to your Sip tutorial ;.P

Now moving onward to my not so obvious stuff...

Thanks for the quick reply. I so much wish I could make use of something
standard such as SSL but unfortunately I can't. I am using Grizzly to
communicate to a legacy device (actually thousands of them...) which
implements its own custom password negotiation protocol. That is why I
need to implement my own protocol. Unfortunately, I only have control of
the code on my client application side, the server side being the legacy
device.

So, what would you recommend?

I think I cannot avoid it, I need to implement my own protocolFilter on
the client side.

My idea is the following...

***** Client Snippet ****

Controller controller = new Controller();
TCPSelectorHandler mySelectorHandler = new TCPSelectorHandler() ;

mySelectorHandler.setProtocolChainInstanceHandler(new
DefaultProtocolChainInstanceHandler(){
        public ProtocolChain poll()
        {
                ProtocolChain protocolChain = protocolChains.poll();
                if (protocolChain == null)
                {
                        protocolChain = new DefaultProtocolChain();
                        protocolChain.addFilter(new ReadFilter());
                        protocolChain.addFilter(new MyProtocolFilter());
                }
                return protocolChain;
        }
});

controller.addSelectorHandler(mySelectorHandler);

...

TCPConnectorHandler myConnectorHandler = (TCPConnectorHandler)
controller.acquireConnectorHandler(Controller.Protocol.TCP);
myConnectorHandler.connect(new InetSocketAddress(host, port));

...

Public class MyProtocolFilter() implements ProtocolFilter
{
        public boolean execute(Context ctx) throws IOException
        {
                - Set custom state information in ctx object according
to my protocol
                - Given a certain custom state stored in the ctx object,
process the message according to the given state.
        }
}

************

Does my pseudo code make sense or am I totally wrong?

How should I go about managing state for my protocol? Should I store
them in the Context object or declare them as private variable in the
MyProtocolFilter() object? The SSLReadFilter seems to hold a private
SSLContext...

I am not sure I understand the life cycle of the MyProtocolFilter? Is my
instance alive as long as I have a connection? It is important for me to
know that since I need to make the appropriate cleanup if the connection
drops or an exception is raised.


Thanks for your help,


Simon

By the way, a tutorial on exception handling using Grizzly could be
great!


-----Original Message-----
From: Jeanfrancois.Arcand_at_Sun.COM [mailto:Jeanfrancois.Arcand_at_Sun.COM]
Sent: February-29-08 4:01 PM
To: users_at_grizzly.dev.java.net
Subject: Re: [Q] How-to client Protocol

Hi Simon (sound french :-))

Simon Trudeau wrote:
> I'm looking for help building a TCP client with a specific protocol :
>
>
>
> If server is password protected:
>
>
>
> 1. Client connects to server
> 2. Server sends password prompt to client
> 3. Client sends server's password
> 4. Server sends acknowledgement
> 5. Client sends request
> 6. Server sends reply
> 7. Repeat step 5 and 6
>
>
>
> If server is not password protected:
>
>
>
> 1. Client connects to server
> 2. Client sends request
> 3. Server sends reply
> 4. Repeat step 2 and 3
>
>
>
> How should I go about implementing this protocol? In once case, the
> client, upon establishing a connection, can send a request right away
in
> the other case, it must wait for the server to negotiate the password.
>
>
>
> What's the right way to handle protocol specific data exchange on the
> client side?

With Grizzly, you don't have to implement such mechanism, as it already
support it by default. I will first explain without too much details, so

feel free to ask questions if I'm unclear. But first, are you planning
to use a single port for both TLS (secure) and TCP (unsecure) or will
you have two ports? We have a mechanism that support a single port:

http://weblogs.java.net/blog/jfarcand/archive/2006/11/one_port_to_rul.ht
ml

Might want to use that (but for now, let's focus on not using it). For
the server side, you need to add to SelectorHandler:

Controller controller = new Controller();
controller.addSelectorHandler(new SSLSelectorHandler());
controller.addSelectorHandler(new TCPSelectorHandler());

This is just a code snippet. Next the client.


>
>
>
> My first guess would be to create a custom CallbackHandler to trigger
> the password negociation upon connecting to the server like so...

Right,



>
>
>
> connector_handler.connect(new InetSocketAddress(host,port),
>
> new CallbackHandler<Context>()
>
> {
>
> public void onConnect(IOEvent<Context> e)
>
> {
>
> SelectionKey k = e.attachment().getSelectionKey();
>
> System.out.println("Callbackhandler: OnConnect...");
>
> try
>
> {
>
> connector_handler.finishConnect(k);
>
>
>
> //*Negociate password password exchange here*
>
> } catch(Exception ex)
>
> {
>
> System.out.println("exception in
CallbackHandler:"+ex.getMessage());
>
> }
>
> e.attachment().getSelectorHandler().register(k,SelectionKey.OP_READ);
>
> }
>
>
>
> public void onRead(IOEvent<Context> e){}
>
> public void onWrite(IOEvent<Context> e){}
>
> });
>
>
>
> It might work... but it definitely doesn't look very nice. Is there
some sort of state machine facility to deal with this kind of situation?
I guess there must be since Grizzly is implemented with protocols such
as SIP.

But how/where is your password (what kind of form does it take). Usually

  you add a certificate on the client and server side, and Grizzly will
do the negociation for you. Is that what you have in mind?



>
>
>
> There is also something called a ProtocolFilter, I guess it could be
better suited than using the CallbackHandler...eventhough I need to
define a behaviour OnConnection...

ProtocolFilter are used on the server side usually (but can be used on
the client side as well...SIP does use it). For your SSL stuff, you will

use the SSLReadFilter, and for TCP/UDP, the ReadFilter. What you usually

do is:

91 Controller sel = new Controller();
92 sel.setProtocolChainInstanceHandler(new
DefaultProtocolChainInstanceHandler(){
93 public ProtocolChain poll() {
94 ProtocolChain protocolChain =
protocolChains.poll();
95 if (protocolChain == null){
96 protocolChain = new DefaultProtocolChain();
97 protocolChain.addFilter(new ReadFilter());
98 protocolChain.addFilter(*** What you need to do

with the bytes ****);
99 }
100 return protocolChain;
101 }
102 });

This is the server side :-)

>
>
>
> Using a ProtocolFilter, how would I go about making it stateful and
maintaining state information between invocation of the ProtocolFilter?
I guess it has something to do with the Context object... But how do you
store user defined states in this object? Do I have to overload it?

Context.setAttribute() or SelectorHandler.setAttribute or
Controller.setAttribute. You can also makes your ProtocolFilter
statefull:

> ProtocolChainInstanceHandler pciHandler =
> new ProtocolChainInstanceHandler() {
>
> final private ProtocolChain protocolChain = new
DefaultProtocolChain();
>
> public ProtocolChain poll() {
> return protocolChain;
> }
>
> public boolean offer(ProtocolChain instance) {
> return true;
> }
> };
> controller.setProtocolChainInstanceHandler(pciHandler);

So you can store you state inside any ProtocolFilter. But


>
>
>
>
>
> Well, I guess I have a lot of interrogations! :.)

Keep them coming :-) Our documentation really really sucks :-)


Are there any test cases in the Grizzly code base that could help me?



Are there any tutorials, code samples, on the topic?

There is a couple on grizzly.dev.java.net. A good starter is:

http://weblogs.java.net/blog/jfarcand/archive/2008/02/writing_a_tcpud_1.
html

and the SIP example is here:

http://weblogs.java.net/blog/jfarcand/archive/2007/11/supporting_the.htm
l

Erick also proposed a tutorial:

http://www.nabble.com/Grizzly-on-the-client-side%2C-a-modest-tutorial-td
15643977.html

But the best source of information is the mailing list. We are all happy

to help so bombard us with questions :-)

Thanks!

-- Jeanfrancois



>
>
>
>
>
> Thanks for your help,
>
>
>
>
>
> Simon
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
For additional commands, e-mail: users-help_at_grizzly.dev.java.net