users@grizzly.java.net

Re: How to handle events initiated from server in Grizzly?

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Fri, 13 Apr 2007 11:19:02 -0400

Hi,

Zheng, Fay wrote:
> Hi Jeanfrancois,
>
> Great! This is really helpful!
>
> There are 3 different conversations that could happen between the client
> and server. The connection is always open
>
> There could be many of those 3 combinations during the life time of the
> connection:
>
> 1. client ------> request -----> server (there's no response back from
> server)
> 2. client ------> request -----> server
> response <--------|
>
> 3. server ------> response -------> client (server just sends a message
> to the client)
>
> It is not a one to one relationship between request and response. They
> are more like events (client events and server events).

Looks very similar to the SIP protocol :-) Then I would recommend you do
something like:

> 1 Controller controller = new Controller();
> 2
> 3 TCPSelectorHandler selectorHandler = new TCPSelectorHandler();
> 4 selectorHandler.setPort(port);
> 5 selectorHandler.setInet(inet);
> 6 selectorHandler.setLinger(linger);
> 7 selectorHandler.setLogger(logger);
> 8 selectorHandler.setReuseAddress(reuseAddress);
> 9 selectorHandler.setSelectTimeout(selectorTimeout);
> 10 selectorHandler.setServerTimeout(serverTimeout);
> 11 selectorHandler.setSsBackLog(ssBackLog);
> 12 selectorHandler.setTcpNoDelay(tcpNoDelay);
> 13 controller.setSelectHandler(selectorHandler);
> 14
> 15 DefaultSelectionKeyHandler keyHandler = new DefaultSelectionKeyHandler();
> 16 keyHandler.setLogger(logger);
> 17 keyHandler.setTimeout(keepAliveTimeoutInSeconds * 1000);
> 18 controller.setSelectionKeyHandler(keyHandler);
> 19
> 20 final DefaultProtocolChain protocolChain = new DefaultProtocolChain();
> 21 protocolChain.addFilter(new ReadFilter());
> 22 protocolChain.addFilter(new ProtocolFilter(){
> 23 public boolean execute(Context ctx) throws IOException {
> 24 ByteBuffer byteBuffer =
> 25 ((WorkerThread)Thread.currentThread()).getByteBuffer();
> 26
> 27 // {Add your logic here}
> 28 // (1) client need a response
> 29 // Flush the response and then add which will register the key
> 30 // back to the Selector for new request:
> 31 ctx.setKeyRegistrationState(Context.KeyRegistrationState.REGISTER);
> 32
> 33
> 34 // Tell Grizzly to not do ANYTHING with the key
> 35 // This is needed to support Asynchonous Request Processing
> 36 // client ---> request ----> server ---> wait until response
> 37 // Here you need to have add a Classback so when the
> 38 // server is ready to push data back to the client, you can
> 39 // resume the connection.
> 40 ctx.setKeyRegistrationState(Context.KeyRegistrationState.NONE);
> 41 return true;
> 42 }
> 43
> 44 public void callBack(ServerCallback serverCallback){
> 45 // Push something to the client
> 46
> 47 // Tell the server you are ready for more client requests.
> 48 controller.getSelectHandler().register(key);
> 49 };
> 50
> 51 }
> 52
> 53 InstanceHandler<ProtocolChain> instanceHandler
> 54 = new InstanceHandler<ProtocolChain>(){
> 55 /**
> 56 * Always return instance of ProtocolChain.
> 57 */
> 58 public ProtocolChain poll(){
> 59 return protocolChain;
> 60 }
> 61
> 62 /**
> 63 * Pool an instance of ProtocolChain.
> 64 */
> 65 public boolean offer(ProtocolChain instance){
> 66 return true;
> 67 }
> 68 };
> 69 controller.setInstanceHandler(instanceHandler);

Now can the client send a request and at the same time the server push a
response? Do you need to support scenarios like:

client --- request1 ---->server
        --- request2 ---->
        <-- response1 ------|
        <-- response2 ------|

Hope that help!

-- Jeanfrancois




>
>
> Thanks,
>
> Fay Zheng
>
> -----Original Message-----
> From: Jeanfrancois.Arcand_at_Sun.COM [mailto:Jeanfrancois.Arcand_at_Sun.COM]
> Sent: Thursday, April 12, 2007 9:23 AM
> To: Zheng, Fay
> Subject: Re: How to handle events initiated from server in Grizzly?
>
> Hi,
>
> Zheng, Fay wrote:
>> I am looking at Grizzly 1.5.
>> Yes. Our server has its own protocols. So we will need our own
>> implementation of StreamAlgorithm and WriteProtocolFilter.
>
> If you are looking at 1.5 and you don't need http support, then all you
> need is to look under grizzly/trunk/modules/grizzly. In that module,
> StreamAlgorithm and all the concept defined in Grizzly 1.0 aren't there
> (with the exception of the Pipeline concept). StreamAlgorithm, Task(s)
> etc. only apply if you are building your server on top of
> grizzly/trunck/modules/http.
>
>
>> The client will keep the TCP connection open as long as it is running.
>> Periodically the client may send one or more requests to the server
> then
>> it can be handled using the following flow:
>>
>> ReadTask --> ProcessTask --> process --> continue if there's any
>> response
>> -->WriterProtoclFilter --> write response
>
> OK this looks very similar to what Comet processing is doing (with
> HTTP).
>
>> Currently our server uses a thread pool to broadcast some message
>> periodically through the existing client connection to all the
> clients.
>> How can I fit those writeTasks in the Grizzly framework?
>
> In order to do that with 1.5, you will need to write three
> ProtocolFilter:
>
> + AsyncReadFilter (which extend com.sun.grizzly.filter.ReadFilter and
> override the postExecute method and only return true (as you don't want
> to neither cancel the SelectionKey nor register it back to Selector (if
> I understand correctly).
>
> + ProcessorFilter (look if response are available) If yes, then invoke
> the WriteFilter. If no, the either send an empty response or invoke the
> next Filter which is ParkFilter (see below).
>
> What you want to be able to do is:
>
> client ------> request -----> server
> response <--------| // If response are available
> response <--------|
>
> If no response, do you want to park the request or just send an empty
> response? Say differently, do you want the client to always wait for a
> response or can a client receive no response and send a request latter
> on?
>
> Do you mind if we continue the discussion on users_at_grizzly.dev.java.net
> or you need to keep the dicussion private (I've no problem keeping it
> private).
>
> Thanks!
>
> -- Jeanfrancois
>
>
>
>
>
>
>
>
>> Thanks,
>>
>> Fay Zheng
>> fzheng_at_ea.com
>> 650.628.2738
>>
>> -----Original Message-----
>> From: Jeanfrancois.Arcand_at_Sun.COM [mailto:Jeanfrancois.Arcand_at_Sun.COM]
>
>> Sent: Wednesday, April 11, 2007 3:07 PM
>> To: Zheng, Fay
>> Subject: Re: How to handle events initiated from server in Grizzly?
>>
>> Hi Fay Zheng,
>>
>> Zheng, Fay wrote:
>>> Hi Jean,
>> In Quebec, we don't have middle name, which means my name is
>> Jeanfrancois :-) :-)
>>
>>>
>>>
>>> We have an existing server application using blocking I/O and
>>> thread-per-connection implementation. We want to add NIO layer (build
>> on
>>> top of Grizzly) to this app to improve capacity. Our existing app not
>
>>> only handle requests from client connection (request-process-response
>
>>> model), but we also have varies events sent to the client that are
>>> initiated by the server. How should we handle those kinds of events
> in
>>> grizzly? Is there a way to plug-in a writerTask pipeline?
>> If I understand correctly, your server is pushing data back to the
>> client using its own protocol, right?
>>
>> Are you looking at Grizzly 1.0 or 1.5? For 1.5, you will need to add a
>
>> WriterProtocolFilter. For 1.0, you are right a WriterTask will do the
>> job. But can you elaborate (if that's not private) on what your are
>> doing exactly? More information will help me understanding your
>> implementation :-)
>>
>> BTW I'm in Brazil this week, giving talks on Grizzly :-) I may reply
>> slowly...hopefully not!
>>
>> Thanks!
>>
>> -- Jeanfrancois
>>
>>
>>
>>>
>>>
>>> Thanks,
>>>
>>>
>>>
>>> Fay Zheng
>>>
>>> fzheng_at_ea.com <mailto:fzheng_at_ea.com>
>>>
>>> 650.628.2738
>>>
>>>
>>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>