Web services test code generator
Klaus Berg has recently released a test-code generator for JUnit-based Web service clients. If you're developing Web services using Axis2 and XMLBeans this wizard could turn your JUnit test client coding into a powerful code generation process. It also has uses for those using GUI-based testing tools like soapUI.

Newsletter sign-up

Sign up for our technology specific newsletters.


Email Address:

Asynchronous HTTP and Comet architectures

An introduction to asynchronous, non-blocking HTTP programming

Comet has popularized asynchronous non-blocking HTTP programming, making it practically indistinguishable from reverse Ajax, also known as server push. In this article, Gregor Roth takes a wider view of asynchronous HTTP, explaining its role in developing high-performance HTTP proxies and non-blocking HTTP clients, as well as the long-lived HTTP connections associated with Comet. He also discusses some of the challenges inherent in the current Java Servlet API 2.5 and describes the respective workarounds deployed by two popular servlet containers, Jetty and Tomcat.

While Ajax is a popular solution for dynamically pulling data requests from the server, it does nothing to help us push data to the client. In the case of a Web mail application, for instance, Ajax would enable the client to pull mails from the server, but it would not allow the server to dynamically update the mail client. Comet, also known as server push or reverse Ajax, enhances the Ajax communication pattern by defining an architecture for pushing data from the server to the client. Comet enables us to push an event from the mail server to the WebMail client, which then signals the incoming mail.

Comet itself is based on creating and maintaining long-lived HTTP connections. Handling these connections efficiently requires a new approach to HTTP programming. In this article I introduce asynchronous, non-blocking HTTP programming and explain how it works. While I do present a Comet application at the end of the article, this style of programming is not restricted to Comet applications. Accordingly, this article describes asynchronous, non-blocking HTTP programming in general.

I start with an overview of client-based asynchronous message handling and message streaming, and then begin demonstrating the many uses of asynchronous HTTP on the server side. I explain the role and current limitations of the Java Servlet API 2.5, and demonstrate the use of the xSocket-http library to work around some of these limitations. The article concludes with a look at a dynamic Web application that leverages the two techniques associated with Comet architectures: long polling and streaming. I also show how this application could be implemented on Jetty and Tomcat, respectively.

Asynchronous message handling

At the message level, asynchronous message handling means that an HTTP client performs a request without waiting for the server response. In contrast, when performing a synchronous call, the caller thread is suspended until the server response returns or a timeout is exceeded. At the application level, code execution is stopped, waiting for the response before further actions can be taken. Client-side synchronous message handling is very easy to understand, as illustrated by the example in Listing 1.

Listing 1. Client example -- synchronous call

      
        HttpClient httpClient = new HttpClient();
        
        // create the request message
        HttpRequest req = new HttpRequest("GET", "http://tools.ietf.org/html/rfc2616.html");

        // the call blocks until the response returns
        HttpResponse resp = httpClient.call(req);

        int status = resp.getStatus();
        // ...

When performing an asynchronous call it is necessary to define a handler, which will be notified if the response returns. Typically, such a handler will be passed over by performing the call. The call method returns immediately. The application-level code instructions after the send statement will be processed without waiting for a server response. The server response will be handled by performing the handler's callback method. If the response returns, the network library will execute the callback method within a network-library-controlled thread. If necessary, the request message has to be synchronized with the response message at the application-code level. An asynchronous call is shown in Listing 2.

Listing 2. Client example -- asynchronous call

     HttpClient httpClient = new HttpClient();
        
        // response handler 
        IHttpResponseHandler responseHandler = new IHttpResponseHandler() {
                        
                public void onResponse(HttpResponse resp) throws IOException {
                        int status = resp.getStatus();
                        // ...
                }

                // ...
        };
        
        
        // create the request message
        HttpRequest req = new HttpRequest("GET", "http://tools.ietf.org/html/rfc2616.html");

        // send the request in an asynchronous way 
        httpClient.send(req, responseHandler);

        // ...

The advantage of this approach is that the caller thread will not be suspended until the response returns. Based on a good network library implementation, no outstanding threads are required. In contrast to the synchronous call approach, the number of outstanding requests is not restricted to the number of possible threads. The synchronous approach requires a dedicated thread for each concurrent request, which consumes a certain amount of memory. This can become a problem if you have many concurrent calls to be performed on the client side.

HTTP pipelining

Asynchronous message handling also enables HTTP pipelining, which you can use to send multiple HTTP requests without waiting for the server response to former requests. The response messages will be returned by the server in the same order as they were sent. Pipelining requires that the underlying HTTP connection is in persistent mode, which is the standard mode with HTTP/1.1. In contrast to non-persistent connections, the persistent HTTP connection stays open after the server has returned a response.

Pipelining can significantly improve application performance when fetching many objects from the same server. The implicit persistent mode eliminates the overhead of establishing a new connection for each new request, by allowing for the reuse of connections. Pipelining also eliminates the need for additional connection instances to perform concurrent requests.

Discuss

Start a new discussion or jump into one of the threads below:

Resources
"COMET - The next stage of AJAX " (Alex Russell, IrishDev.com, March 2006) introduced the term Comet to describe the event-driven, server-push data streaming pattern discussed in this article. "New features added to Servlet 2.5" (Jason Hunter, JavaWorld, January 2006) continues the author's JavaWorld series of articles documenting the evolution of the Java Servlet API. "Master Merlin's new I/O classes" (Michael Nygard, JavaWorld, September 2001) introduces the java.nio packages and their premise: to allow Java applications to handle thousands of open connections while delivering scalability and performance. "Architecture of a highly scalable NIO-based server" (Gregor Roth, Java.net, February 2006) describes the fundamental patterns that are used to realize the architecture of a connection-oriented NIO-based server. "Mastering Ajax: Write scalable Comet applications with Jetty and Direct Web Remoting" (Philip McCarthy, IBM developerWorks, July 2007) further introduces the Comet pattern and Jetty 6's Continuations API. "Scripting on the Java platform" (Gregor Roth, JavaWorld, November 2007) features a non-blocking, multithreaded SMTP server example written using JRuby and Java. xSocket-http is an extension module of the NIO-based network library xSocket. The documentation for the current HTTP specification  HTTP/1.1 also includes a definition of chunked transfer encoding. JSR 315: JavaServlet 3.0 Specification documents the current state of Java Servlet API 3.0 The Jetty documentation Wiki includes a page on how Jetty 6 uses continuations to work around the limitations of the Java Sevlet API 2.5. "Advanced IO and Tomcat" describes Tomcat's support for asynchronous message handling and Comet. See the Grizzly project homepage to learn more about Grizzly's approach to Comet. You'll find good, short explanations of HTTP pipelining as well as Comet strategies such as long polling, streaming, and the forever frame implementation on Wikipedia. See the JavaWorld Development Tools Research Center for more about tools, frameworks, and APIs for Java development. Also see Network World's IT Buyer's Guides: Side-by-side comparison of hundreds of products in over 70 categories.



You are viewing a mobilized version of this site...
View original page here

Mobilized by Mowser Mowser