Newbie question: Understanding CallbackHandler

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Newbie question: Understanding CallbackHandler

CigarMan
I have been trying to use Grizzly for the past couple of days to write an asynchronous TCP/UDP client. Basically, I want my client to write a bunch of bytes (request) to a remote server and eventually receive a response as a bunch of bytes.

Looking at the unit tests available with Grizzly framework module, it looks like I have to write a callbackhandler to handle the asynchronous response. Unfortunately I don't understand the callbackHandler interface.

In  TCPAsynchQueueReaderTest.java, the method public void onConnect(IOEvent<Context> ioEvent) seems to register a key with the OP_READ event.

 ioEvent.attachment().getSelectorHandler().register(key, SelectionKey.OP_READ);

First of all, I'm kind of lost to what that whole registration means, I have very little cue as to what this onConnect method is trying to achieve (I would really appreciate if you could post references on your websites so that new developpers can get the appropriate background knowledge before digging into your framework). I assume this has to do with having the selectionKey try to perform a read operation once a connection is established with the client.

But yet in the same example, the onRead and onWrite method do nothing!

Basically, as a user, I need to know where can I put my application code that will get the bytes received and perform my business logic (I would really like to understand how to write a callbackhandler! :.).

Is there a higher level API provided with the Grizzly framework for writing basic clients and servers that send bytes over TCP/UDP (not HTTP)?

Also, one last question (for now :.), do I need a protocol filter on the server side if every write operation write operation from the client writes a full request to the channel? (Sorry, I don't really understand behind the rationale of the protocolfilter, I don't really understand what kind of issue it addresses.


Thanks for your help,


Simon


P.S.: Don't hesitate to write back in french if you feel like it, I'm from Montreal.

Once I get a better understanding of how to write a basic Grizzly asynch client and server, I will try to write a tutorial for newbies (like myself) about it. I'll let you know.
Reply | Threaded
Open this post in threaded view
|

Re: Newbie question: Understanding CallbackHandler

Jeanfrancois Arcand-2
Salut,

CigarMan wrote:

> I have been trying to use Grizzly for the past couple of days to write an
> asynchronous TCP/UDP client. Basically, I want my client to write a bunch of
> bytes (request) to a remote server and eventually receive a response as a
> bunch of bytes.
>
> Looking at the unit tests available with Grizzly framework module, it looks
> like I have to write a callbackhandler to handle the asynchronous response.
> Unfortunately I don't understand the callbackHandler interface.
>
> In  TCPAsynchQueueReaderTest.java, the method public void
> onConnect(IOEvent<Context> ioEvent) seems to register a key with the OP_READ
> event.
>
>  ioEvent.attachment().getSelectorHandler().register(key,
> SelectionKey.OP_READ);
>
> First of all, I'm kind of lost to what that whole registration means, I have
> very little cue as to what this onConnect method is trying to achieve (I
> would really appreciate if you could post references on your websites so
> that new developpers can get the appropriate background knowledge before
> digging into your framework). I assume this has to do with having the
> selectionKey try to perform a read operation once a connection is
> established with the client.
>
> But yet in the same example, the onRead and onWrite method do nothing!

You should take a look at the TCPConnectorHandler/UDPConnectorHandler as
a starter. They allow you to read/write bytes easily.

>
> Basically, as a user, I need to know where can I put my application code
> that will get the bytes received and perform my business logic (I would
> really like to understand how to write a callbackhandler! :.).

Right. The CallBackHandler is exactly what you need to customize and set
on the ConnectorHandler. As a very simple example:

>         private final CallbackHandler createTCPCallbackHandler
>                     (final ConnectorHandler connectorHandler, final TargetTuple tt){
>             CallbackHandler<Context> callbackHandler = new CallbackHandler<Context>() {
>

Below is the onConnect implementation that you can use as it is.

>                 public void onConnect(IOEvent<Context> ioEvent) {
>                     SelectionKey key = ioEvent.attachment().getSelectionKey();
>                     connectorHandler.finishConnect(key);
>                     controller.registerKey(key, SelectionKey.OP_READ,
>                                 Controller.Protocol.TCP);
>                 }
>

The onRead will be called when bytes are available.

>                 public void onRead(IOEvent<Context> ioEvent) {
>                     try {
>                         Context ctx = ioEvent.attachment();
>                         SelectionKey key = ctx.getSelectionKey();
>                         if (!key.isValid()) {
>                             return;
>                         }
>
>                         // disable OP_READ on key before doing anything else
>                         key.interestOps(key.interestOps() & (~SelectionKey.OP_READ));
                          // READ bytes
                          ((SocketChannel)key.channel()).read(ByteBuffer)
                         // Do something with the bytes

>                     }
>                 }
>

the onWrite will be invoked when bytes are available.

>                 public void onWrite(IOEvent<Context> ioEvent) {
                        // Write your bytes
                      ((SocketChannel)key.channel()).write(ByteBuffer)

>                 }
>             };
>             return callbackHandler;
>         }

So a simple snipet would consist of:

TCPConnectorHandler mtCh = new TCPConnectorHandler();
mtCh.setCallbackHandler(new MyCallBackHandler());
mtCh.connect(...);

...

mtCh.read(ByteBuffer, true);

...

mtCh.write(ByteBuffer, true);


Here you will use a special read/write functionality Grizzly is
offering, which is to read/write bytes using a temporary Selector pool.
It behave the same way as blocking IO, but using non-blocking IO under
the hood, giving great performance.

>
> Is there a higher level API provided with the Grizzly framework for writing
> basic clients and servers that send bytes over TCP/UDP (not HTTP)?

The TCPConnectorHandler/UDPConnectorHandler is the place to start. Have
you see this blog:

Yes our documentation is really bad...we are working to fix the problem.

>
> Also, one last question (for now :.), do I need a protocol filter on the
> server side if every write operation write operation from the client writes
> a full request to the channel? (Sorry, I don't really understand behind the
> rationale of the protocolfilter, I don't really understand what kind of
> issue it addresses.

Since you only need client side component, you don't need to use
ProtocolFilter/ProtocolChain. You usually use them when you write a
server side component, or you use a protocol (like SIP) where a client
can becomes a server, and vice versa.

For now, let's work on the TCPConnectorHandler/UDPConnectorHandler.


>
>
> Thanks for your help,
>
>
> Simon
>
>
> P.S.: Don't hesitate to write back in french if you feel like it, I'm from
> Montreal.

Hey hey :-)

>
> Once I get a better understanding of how to write a basic Grizzly asynch
> client and server, I will try to write a tutorial for newbies (like myself)
> about it. I'll let you know.

That would be great!!!

Thanks

-- Jeanfrancois


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]