users@grizzly.java.net

Re: Seeking Some Guidance on Using Grizzly / NIO

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Wed, 29 Apr 2009 14:52:57 +0200

Ok, so one more time for Grizzly 1.x :)

>
> What i'm trying to do is a very simple TCP relay server.
>
> 1. i will listen to incoming TCP connections on a port.
>
> 2. Whenever an incoming connection is made, i will initiate a
> corresponding outgoing connection to the target server. (i.e.. from
> the perspective of my server, there is a 1 - 1 mapping between the
> incoming connections and the outgoing connections).
>
> 3. When i receive some bytes from one of the incoming connection, i
> will store it. When the bytes make up a complete message, i will
> send out the whole message to the target server through the outgoing
> connection that corresponds to the incoming connection through which
> the message is received.
>
> 4. Same thing vice-versa. When i receive a response from an outgoing
> connection, i will forward it back through the corresponding
> incoming connection.
>
> 5. When a connection is closed - either the incoming or outgoing
> connection - i will close the corresponding other connection.
>
> Now this is what i think i should do (may be horribly off-track!).
>
> 1. Initiate a Controller.
>
> 2. Add TCPSelectorHandler to Controller.
>
> 3. Set a ProtocolChainInstanceHandler to the Controller.
>
> 4. In the ProtocolChainInstanceHandler, i will have the ReadFilter,
> and MyOwnFilter.
>
> 5. MyOwnFilter is where i do the work of retrieving bytes from the
> ByteBuffer (from current WorkerThread), storing it somewhere,
> checking whether a complete message has already been formed, and
> sending it out if it has.
Right.
For parsing message you can actually use ParserProtocolFilter instead
of ReadFilter. Here are some refs:
http://weblogs.java.net/blog/sdo/archive/2007/12/grizzly_protoco.html
https://grizzly.dev.java.net/tutorials/tutorial-framework-filter-sample/index.html

>
> 6. The above is for the server part. For the client part, i will
> instantiate another Controller (or can i use the same Controller
> instance?)
You can use the same one.

> , and add a TCPSelectorHandler (instantiated in client mode).
Not required. You can use the same Controller and SelectorHandler as
for server part.

> Also for this controller, set the ProtocolChainInstanceHandler which
> will have another ReadFilter and AnotherMyOwnFilter.
> AnotherMyOwnFilter will read the bytes and forward it back through
> the corresponding incoming connection.
The same as above. You can reuse one from server side.


> Some questions:
>
> 1. How do i listen for and get the event where an incoming
> connection is accepted? i will need to create a corresponding
> outgoing connection with the target server.
Actually here you can either override
TCPSelectorHandler.acceptWithoutRegistration() like:

MyTCPSelectorHandler extends TCPSelectorHandler {
      @override
      public SelectableChannel acceptWithoutRegistration(SelectionKey
key) throws IOException {
               SelectableChannel channel = super.
acceptWithoutRegistration(key);
              <--- do something with accepted channel ---->
              return channel;
      }
}

Or as alternative, you can create "corresponding" connection first
time some data will come on primary connection.


> 2. And also, how can i get hold of the channel associated with this
> incoming connection? i will need this channel to forward response
> back later on.
You'll probably need to create Map<SelectableChannel,
SelectableChannel> or two Maps in MyOwnFilter, where you'll map
corresponding connections in both directions: primary ->
"corresponding", "corresponding" -> primary.


>
> 3. How do i initiate and establish an outgoing connection with the
> target server, and get hold of the channel associated with the
> outgoing connection?
You can use ConnectorHandler like:
                 final TCPConnectorHandler tcpConnector = new
TCPConnectorHandler();
                 tcpConnector.connect(new
InetSocketAddress("localhost", PORT));

> 4. How do i listen for and get the event of a connection closed by
> the other party?
You'll need to register listener on SelectionKeyHandler like:

DefaultSelectionKeyHandler selectionKeyHandler = new
DefaultSelectionKeyHandler(selectorHandler);
selectionKeyHandler.setConnectionCloseHandler(new
ConnectionCloseHandler() {
     public void locallyClosed(SelectionKey key) {
     .....
     }

     public void remotlyClosed(SelectionKey key) {
        ......
     }
});

selectorHandler.setSelectionKeyHandler(selectionKeyHandler);

>
> Thanks very much in advance!
You're welcome :)

WBR,
Alexey.
>
>
>
>
> Regards,
> Edwin
>
>
>
> New Email names for you!
> Get the Email name you&#39;ve always wanted on the new @ymail and
> @rocketmail.
> Hurry before someone else does!
> http://mail.promotions.yahoo.com/newdomains/sg/
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>