#2 is easy
in the Grizzly initialization code add this:
selectorHandler.setSelectionKeyHandler(new BaseSelectionKeyHandler());
because DefaultSelectionKeyHandler implementation has expiration
logic, which is actually useful against DoS attacks etc...
#1 not sure... I need some time to take a look closer at the parser
code.
just one question to be sure... 2nd message never gets parsed, or
sometimes it works, sometimes not?
Thanks.
WBR,
Alexey.
On Jul 15, 2008, at 17:46 , Survivant 00 wrote:
> thanks it works.. but my problems are not done yet.
>
> #1 -
> I'm able to send multiple request to the server, but there is a bug.
>
> The first filter taht parse the query doesn't parse the second query.
>
> I'm able to test with.. in DEBUG.. I put a breakpoint on the method
> isExpectingMoreData
>
> and when I resume.. it will parse the next query.. that's wierd..
>
> I reset my flag in the method
> public boolean releaseBuffer() {
> //System.out.println("releaseBuffer");
>
> if(f_cumulatifBB != null) {
> f_cumulatifBB.clear();
> }
> f_cumulatifBB = null;
>
> eoqFound = false;
>
> return false;
> }
>
>
> maybe this is not called when I return the message with getMessage();
>
>
> #2 -
>
> I got disconnected after 30 sec. why ? is it the default timeout
> value in grizzly ?
>
> what do I need to do to get never expired ?
>
>
>
>
>
>
> 2008/7/15 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
> Thanks for sources.
> In your implementation you define ClientConnectionHandler to
> represent one single client connection during its life-cycle.
> Probably in this case I would suggest to use attachments
> (ThreadAttachment).
> Here what I'm proposing...
>
> private ClientConnectionHandler retrieveConnectionHandler(Context
> context) {
> ClientConnectionHandler clientConnectionHandler = null;
>
> AttributeHolder connectionAttrs =
> ctx.getAttributeHolderByScope(AttributeScope.CONNECTION);
> if (connectionAttrs != null) {
> clientConnectionHandler = (ClientConnectionHandler)
> connectionAttrs.getAttribute(CLIENT_CONNECTION_HANDLER_ATTR);
> } else {
> WorkerThread workerThread = (WorkerThread)
> Thread.currentThread(); // Detach the current Thread data.
> connectionAttrs = workerThread.getAttachment();
> // Attach it to the SelectionKey so the it can be
> resumed latter.
> key.attach(connectionAttrs);
> }
>
> if (clientConnectionHandler == null) {
>
> clientConnectionHandler = new
> ClientConnectionHandler(manager, context.getSelectionKey(),
> context.getSelectorHandler());
>
> connectionAttrs.setAttribute(CLIENT_CONNECTION_HANDLER_ATTR,
> clientConnectionHandler);
> }
>
> return clientConnectionHandler;
> }
>
> this could be the way how to get ClientConnectionHandler associated
> with the specific connection or create new if required.
> See complete QuoteQueryManagerFilter source.
>
> Not sure this will work as it is... as I didn't try to compile it -
> but hope it's clear enough to understand what I meant :)
>
> Thanks.
>
> WBR,
> Alexey.
>
> package org.sample.nio.connection.handler.filter;
>
> import java.io.IOException;
> import java.net.SocketAddress;
> import java.nio.ByteBuffer;
> import java.nio.channels.DatagramChannel;
> import java.nio.channels.SelectableChannel;
> import java.nio.channels.SelectionKey;
> import java.util.logging.Level;
>
> import org.sample.nio.QuoteManager;
> import org.sample.nio.connection.handler.ClientConnectionHandler;
>
> import com.sun.grizzly.Context;
> import com.sun.grizzly.Controller;
> import com.sun.grizzly.ProtocolFilter;
> import com.sun.grizzly.ProtocolParser;
> import com.sun.grizzly.SelectorHandler;
> import com.sun.grizzly.TCPSelectorHandler;
> import com.sun.grizzly.filter.ReadFilter;
> import com.sun.grizzly.util.OutputWriter;
>
>
> public class QuoteQueryManagerFilter implements ProtocolFilter {
> private static final String CLIENT_CONNECTION_HANDLER_ATTR =
> "connection-handler";
>
>
> private QuoteManager manager;
>
> public QuoteQueryManagerFilter(QuoteManager manager) {
> this.manager = manager;
> }
>
> public boolean execute(Context context) throws IOException {
> String query = (String)
> context.removeAttribute(ProtocolParser.MESSAGE);
>
> if(query==null || query.trim().length()==0){
> return false;
> }
>
> System.out.println("query = " + query);
>
> //here should be the parsed query command string with
> // which query should be able to create a command
> // I have no time to rewrite ClientConnectionHandler
> // Basically you have in context a link to client connection
> //with that and for example TCPSelectorHandler your commands
> can
> //send data to client
>
> /*
> * For now instead of keeping whole Context, you can just
> keep SelectionKey as reference to the client,
> * and send response back using:
> selectorHandler.getAsyncQueueWriter().write(SelectionKey, ...);
> */
>
> // on va chercher le ClientConnectionHandler si il existe
>
> ClientConnectionHandler clientConnectionHandler =
> retrieveConnectionHandler(context);
>
> manager.processQuery(clientConnectionHandler, query);
>
>
> // // Depending on protocol perform echo
> // //SelectableChannel channel =
> context.getSelectionKey().channel();
> // try {
> //
> // ByteBuffer writeBuffer =
> ByteBuffer.allocateDirect(query.length());
> //
> // writeBuffer.put(query.getBytes());
> //
> // writeBuffer.flip();
> //
> // SelectionKey key = context.getSelectionKey();
> //
> // SelectorHandler selectorHandler =
> context.getSelectorHandler();
> //
> //
> selectorHandler.getAsyncQueueWriter().write(key,writeBuffer);
> //
> // /*
> // if (context.getProtocol() ==
> Controller.Protocol.TCP) { // TCP case
> // OutputWriter.flushChannel(channel, writeBuffer);
> // }
> // */
> // //
> context.getAsyncQueueWritable().writeToAsyncQueue(writeBuffer, null,
> null, true);
> // } catch (IOException ex) {
> // throw ex;
> // }
>
> /*
> * The former will block until all the bytes are written.
> When I say block,
> * I mean the calling Thread will block. The OutputWriter
> internally use a pool of
> * temporary Selector to make sure writes are always executed
> entirely.
>
> With async queue write (the later), the calling
> thread will not block. instead,
> the async queue mechanism will make sure your write
> operation is successful.
> Depending on the protocol, picking one or the other
> make a big difference.
> HTTP use OutputWriter, SIP use async queue.
>
> */
>
> return true;
> }
>
> public boolean postExecute(Context context) throws IOException {
> return true;
> }
>
> private ClientConnectionHandler retrieveConnectionHandler(Context
> context) {
> ClientConnectionHandler clientConnectionHandler = null;
>
> AttributeHolder connectionAttrs =
> ctx.getAttributeHolderByScope(AttributeScope.CONNECTION);
> if (connectionAttrs != null) {
> clientConnectionHandler = (ClientConnectionHandler)
> connectionAttrs.getAttribute(CLIENT_CONNECTION_HANDLER_ATTR);
> } else {
> WorkerThread workerThread = (WorkerThread)
> Thread.currentThread(); // Detach the current Thread data.
> connectionAttrs = workerThread.getAttachment();
> // Attach it to the SelectionKey so the it can be
> resumed latter.
> key.attach(connectionAttrs);
> }
>
> if (clientConnectionHandler == null) {
>
> clientConnectionHandler = new
> ClientConnectionHandler(manager, context.getSelectionKey(),
> context.getSelectorHandler());
>
> connectionAttrs.setAttribute(CLIENT_CONNECTION_HANDLER_ATTR,
> clientConnectionHandler);
> }
>
> return clientConnectionHandler;
>
> }
> }
>
> On Jul 15, 2008, at 15:00 , Survivant 00 wrote:
>
>
>
> 2008/7/15 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
> Ok :))
>
> Can you pls. attach all Grizzly related sources - it will help a
> lot :)
>
> Thanks.
>
> WBR,
> Alexey.
>
> On Jul 15, 2008, at 14:52 , Survivant 00 wrote:
>
> euh, sorry it was the only way that I found a sample. That why I
> asked the questions.. maybe the problem is there, but like I didn't
> know other way..
>
>
>
> 2008/7/15 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
> I'll explain my needs from the start.
>
> it's for a stock quote simulator.
>
> when a client connect to the server, it will send requests.
>
> like that
>
> client 1 -> - want the feed for the symbol | aaa
> - want the feed for the symbol | bbb
>
> client 2 -> - want the feed for the symbol | aaa
>
>
> In the server using grizzly :
>
> I have 2 filters in the chains.
>
> - the first for parsing the messages
> - the second for processing the message
>
> I need to keep a reference for all the clients and know which feed
> they register to.
>
> When I process to message, I'll receive the response from a 3th
> party later, and I 'll receive it on a callback method, and I'll
> send back the response to the client register as soon as the
> response arrive.
>
>
> The main problem that I had was that in the second filter, I need to
> know if the client already ask for a feed and I need to know how to
> send it back to data. That why I wanted to use a
> ClientConnectionHandler ( before using grizzly, I created the
> cleintconnectionhandler just after the socketserver.accept() ) to
> keep the selectionKey and the channel to send the data back.
>
>
> if I loop into your sample.. it will create a pool each time the
> client send a message.
> Why? You're using stateful ProtocolChain? In other words you have
> protocol chain, associated with each client connection?
>
> WBR,
> Alexey.
>
>
>
>
>
> 2008/7/15 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
> Hi,
>
> your implementation is ok.
> Though if having the map of all client connections is not must -
> then you can create ClientConnectionHandler pool like inline...
>
> public class QuoteQueryManagerFilter implements ProtocolFilter {
>
> ConcurrentLinkedQueue<ClientConnectionHandler> pool = new
> ConcurrentLinkedQueue<ClientConnectionHandler>();
> private QuoteManager manager;
>
> public QuoteQueryManagerFilter(QuoteManager manager) {
> this.manager = manager;
> }
>
> public boolean execute(Context context) throws IOException {
> String query = (String)
> context.removeAttribute(ProtocolParser.MESSAGE);
>
> if(query==null || query.trim().length()==0){
> return false;
> }
>
> System.out.println("query = " + query);
>
> //here should be the parsed query command string with
> // which query should be able to create a command
> // I have no time to rewrite ClientConnectionHandler
> // Basically you have in context a link to client connection
> //with that and for example TCPSelectorHandler your commands
> can
> //send data to client
>
> /*
> * For now instead of keeping whole Context, you can just
> keep SelectionKey as reference to the client,
> * and send response back using:
> selectorHandler.getAsyncQueueWriter().write(SelectionKey, ...);
> */
>
> // on va chercher le ClientConnectionHandler si il existe
>
> ClientConnectionHandler clientConnectionHandler =
> pool.poll();
> if (clientConnectionHandler != null) {
> clientConnectionHandler.init(manager,
> context.getSelectionKey(), context.getSelectorHandler());
> } else {
> clientConnectionHandler = new
> ClientConnectionHandler(manager, context.getSelectionKey(),
> context.getSelectorHandler());
> }
>
> // ClientConnectionHandler clientConnectionHandler = null;
>
> //
> if(manager.selectionKeyMap.containsKey(context.getSelectionKey())){
> // clientConnectionHandler =
> manager.selectionKeyMap.get(context.getSelectionKey());
> // } else {
> // clientConnectionHandler = new
> ClientConnectionHandler(manager, context.getSelectionKey(),
> context.getSelectorHandler());
> // }
>
> manager.processQuery(clientConnectionHandler, query);
>
>
>
> and then return ClientConnectionHandler to the pool from processing
> thread.
> In example above single ClientConnectionHandler could be associated
> with different client connections, but not at the same time.
>
> If you need to associate ClientConnectionHandler with just one
> client connection during its life-cycle - may be it makes sense to
> use ThreadAttachment's attributes.
> Let me know if this is required.
>
> Thanks.
>
> WBR,
> Alexey.
>
>
>
> 2008/7/15 Oleksiy Stashok <Oleksiy.Stashok_at_sun.com>:
> Hi,
>
>
> I have a chain of 2 filters.
>
> #1 - parsing the request
> #2 - processing the request
>
> and loop until the client quit.
>
> I want to kept the info about the connection like :
> context.getSelectionKey(), context.getSelectorHandler() in a Object
> like :
>
> ClientTracker(SelectionKey key, SelectorHandler selectorHandler)
>
> and I'll send data back to the client using the key and the
> selectorhandler.
>
> but I don't know where to create that class (ClientTracker) and
> where to put it to use it later.
>
> if I create the ClientTracker into the 2 filters.. a new reference
> will be created each time the client send a request.. it's not what
> I want.
>
> I tought of putting the ClientTracker in the context and check if
> the class exist in the context.. but like the context could be
> invalidate, I could lose the info..
>
> Normally, I would have created the ClientTracker equivalent class,
> after the socketserver.accept();
>
> Do you want to store somewhere complete map of clients
> (ClientTracker), which are currently connected?
> Also, can you pls. provide more details how you want to use
> ClientTracker class? Some code snippets...
>
> Thank you.
>
> WBR,
> Alexey.
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>
>
>
>
>
>
>
>
> <
> demo3
> .zip
> >---------------------------------------------------------------------
>
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>
>