 |
Understanding Grizzly part I: Embedding Grizzly HTTP Web Server in 5 lines
Posted by jfarcand on December 08, 2006 at 11:33 AM | Comments (7)
Grizzly is more and more embedded in frameworks and products, and since the documentation is not as good as I would like, let's start a series of blogs that explain how to embed and extend the framework. All islands are available, I just need to describe how to move from island to island :-).
The main entry point when embedding Grizzly is the SelectorThread. This class contains all the methods required to configure, start and stop the framework. Unfortunately, the number of methods is very large, making life difficult for new user. The good news is I'm currently working on refactoring that class and hiding all the methods that aren't required. OK enough wording......below is a simple example that instantiate the SelectorThread, configure it for tcp/http support and starts it:
63 SelectorThread selectorThread = new SelectorThread();
64 selectorThread.setPort(port);
65 selectorThread.setAdapter(
66 new StaticResourcesAdapter());
67 selectorThread.initEndpoint();
68 selectorThread.startEndpoint();
First, you create the SelectorThread and set the TCP port on which the server will listen to requests. Next is to set an implementation of Adapter class (line 65). The Adapter is the glue code between the Grizzly framework and the program that embed Grizzly. In the example below, the StaticResourcesAdapter is servicing static html pages. The important method is:
101 public void service(Request req, final Response res) throws Exception {
102 MessageBytes mb = req.requestURI();
103 ByteChunk requestURI = mb.getByteChunk();
104
Grizzly parse the tcp/http request and store the result inside the Request and Response object and pass them to the Adapter.service() method. Those objects can then be used to get information about the request,configure the response, and flush it back to the client:
152 res.setContentLength((int)resource.length());
153 ((SocketChannelOutputBuffer)res.getOutputBuffer()).flush();
154
155 SocketChannel socketChannel =
156 ((SocketChannelOutputBuffer)res.getOutputBuffer()).getChannel() ;
157 FileInputStream stream = new FileInputStream(resource);
158 FileChannel fileChannel = stream.getChannel();
159
160 long nread =0;
161 while (nread < resource.length() && socketChannel.isOpen()) {
162 nread += fileChannel.transferTo(nread, fileChannel.size(),
163 socketChannel);
164 }
The complete implementation can be found here.It may look complicated but it is really really easy to implement an Adapter. You can see Takai extension here for JRuby support in GlassFish, and Brian's Grizzly Asynchronous Request Processing (ARP) implementation. What about the thread pool used by Grizzly(called Pipeline)? By default, it use the one that showed the best performance, and use only 20 threads. That will be the topic of my next blog on Understanding Grizzly.
technorati: grizzly web server embedded
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
Jean-Francois,
I tried to start two SelectorThread endpoints in one class and the first thread never returned to allow the main to start the second.
How can I accomplish this?
My end goal is to basically create two simple servers on ports 8080 and 9090 and create a pass-through proxy where the input request stream of the first is wired to the second server whose port is being held open indefinitely.
Any idea on the simplest way to create this?
Jeff
Posted by: tblack on February 13, 2007 at 02:49 PM
-
Right. By default, the SelectorThread will execute on the same thread as the client. To implement what you want, just do SelectorThread.start() instead of SelectorThread.startEndpoint(). Thanks!
Posted by: jfarcand on February 13, 2007 at 03:15 PM
-
Hi,
I tried your code to run WebServer by starting SelectorThread but when i tried to get index.html file from the server, it return blank page example http://localhost:8082/index.html , i just want to access some static file, let me know how to do this.I have index.html file in the start directory.
I used port 8082 .
Thanks for your great work.
Pai
Posted by: paipiski on March 04, 2007 at 02:16 PM
-
Hi, have you added the proper location when you started Grizzly. Something like java -jar grizzly.jar 8082 PATH_TO_INDEX.html? Thanks!
Posted by: jfarcand on March 05, 2007 at 07:42 AM
-
Hi, I am trying to use this example in my implementation of a binding component in JBI, but for some reason the call to selectorThread.startEndpoint() hangs forever. If I implement it as a standalone java application it works as it should, but not within JBI (in glassfish). Any idea what might be the problem?
Posted by: ermhawi on January 28, 2008 at 07:59 AM
-
Which version are you using? startEndpoint block because it start listening on the port you selected. Try using SelectorThread.listen() method or spawn a thread that invoke startEndpoint(). Next time if you can post your question on users@grizzly.dev.java.net....a lot of code/peoples can help!
Thanks!
Posted by: jfarcand on January 28, 2008 at 08:14 AM
-
hi
how to publish my papers
help me
please
Posted by: energyglassfish on June 29, 2008 at 10:11 AM
|