|
|
||
Jean-Francois Arcand's BlogUnderstanding Grizzly part III: Implementing your own protocol on top of the animalPosted by jfarcand on December 12, 2006 at 07:22 PM | Comments (5)Extending Grizzly to support any tcp protocols is not complex. This time I will explain how to customize the current framework to support other protocols than HTTP. In part I and part II, I've explained how to embed Grizzly and how to configure its thread pool. This time let me give some details about how a request is handled in Grizzly, and how to extends the current implementation.
All tcp requests are accepted by the SelectorThread.doSelect(). Technically, it means the SelectionKey's operation-set bit for socket-accept operations (OP_ACCEPT) is handled with the same thread (see SelectorThread.handleAccept()). Next the operation-set bit for read operations (OP_READ) is delegated to the Pipeline (thread pool). The Pipeline can execute any Task implementation. A Task is a Runnable object augmented with some Grizzly specific methods. For handling OP_READ, the SelectorThread will get from its pool an instance of ReadTask. By default, Grizzly at startup creates a pool of DefaultReadTask instances. This task is responsible for reading the initial bytes, decide if there is enough bytes to continue the processing, and then handle the decision to keep-alive the connection or not. The StreamAlgorithm is where you implement the logic to decide if there is enough bytes available to process the request. Any implementation of a StreamAlgorithm will need to take care of managing its ByteBuffer life cycle (creating, pooling, recycling etc.) and decide if more bytes are needed before continuing the request processing. Hence this is where protocols specifics parsing logic needs to be implemented. The easiest way to start with a StreamAlgorithm implementation is by extending the StreamAlgorithmBase and implement the parse method: The example above is a parser which seek for the request path (ex: /grizzly/Servlet) and the protocol used (FOO/1.1). This parser will support request that takes the form of "FOO /foo FOO/FOO". The parse() method will return true if the request processing can continue, or false if the StreamAlgorithm needs more bytes to take a decision. If more bytes are needed, the SelectionKey will be registered back to the Selector and will be reprocessed once bytes are available. If there is enough bytes, the ReadTask will delegate the request processing to an instance of ProcessorTask. The ProcessorTask is where the request processing needs to happens. As an example, in GlassFish, this is where the HTTP protocol is parsed and the Servlet Container invoked. Take a look at the DefaultProcessorTask to see how the HTTP protocol is handled. The main methods to implement is the process() and initialize(): If you look at the ProcessorTask interface, you will soon realize there is a lot of methods to implement. The reason is because Grizzly asynchronous request processing ARP mechanism needs all of them to execute an asynchronous request. I will soon describe in this series of blogs how to implement an asynchronous protocol implementation, but if you don't plan to use ARP, just take a look at the Jetty ProcessorTask implementation. To recap, to implement a tcp protocol with Grizzly you first need to implement a StreamAlgorithm and a ProcessorTask. Next you need to extends the SelectorThread so it can configure those instances and pool them: OK this might looks difficult, but it isn't :-). In case you don't want to implement a StreamAlgorithm, you can always delegate all the processing to the ProcessorTask. The InputStream passed to the ProcessorTask.process() uses a pool of Selector under the hood, so you are guarantee to get all the bytes. But this approach is similar to a socket blocking approach, and may need consume more threads depending on what your protocol is. Euhhh...enough for this blog :-) Next time I will discuss how you can implement a ReadTask from scratch, and introduce some asynchronous protocol processing concept. technorati: grizzly web server embedded Bookmark blog post: CommentsComments are listed in date ascending order (oldest first) | Post Comment
| ||
|
|