|
Jetty and Comet
The Jetty server uses a slightly different technique to enable a scalable implementation of Comet. Jetty supports the programming construct known as continuations. The idea is simple enough. A request is suspended and continued at some point in the future. The resumption could happen either because of a timeout or some other, meaningful event. While the request is suspended, its thread is freed up.
You can use Jetty's org.mortbay.util.ajax.ContinuationSupport class to create an instance of org.mortbay.util.ajax.Continuation for any HttpServletRequest. This allows for a very different approach to Comet. However, continuations can be used to implement a logically identical style of Comet. Listing 6 shows the weather servlet from Listing 2 after it has been "ported" to Jetty.
Listing 6. Jetty Comet servlet
public class JettyWeatherServlet extends HttpServlet {
private MessageSender messageSender = null;
private static final Integer TIMEOUT = 5 * 1000;
public void begin(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
request.setAttribute("org.apache.tomcat.comet", Boolean.TRUE);
request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
messageSender.setConnection(response);
Weatherman weatherman = new Weatherman(95118, 32408);
new Thread(weatherman).start();
}
public void end(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
synchronized (request) {
request.removeAttribute("org.apache.tomcat.comet");
Continuation continuation = ContinuationSupport.getContinuation
(request, request);
if (continuation.isPending()) {
continuation.resume();
}
}
}
public void error(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
end(request, response);
}
public boolean read(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
throw new UnsupportedOperationException();
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
synchronized (request) {
Continuation continuation = ContinuationSupport.getContinuation
(request, request);
if (!continuation.isPending()) {
begin(request, response);
}
Integer timeout = (Integer) request.getAttribute
("org.apache.tomcat.comet.timeout");
boolean resumed = continuation.suspend(timeout == null ? 10000 :
timeout.intValue());
if (!resumed) {
error(request, response);
}
}
}
public void setTimeout(HttpServletRequest request, HttpServletResponse response,
int timeout) throws IOException, ServletException,
UnsupportedOperationException {
request.setAttribute("org.apache.tomcat.comet.timeout", new Integer(timeout));
}
}
The most important thing to notice here is how the structure mimics the Tomcat version of the code. The begin, read, end, and error methods match up to the same events in Tomcat. The servlet's service method is overridden to create a continuation when the request first comes in and suspends it until either the timeout is hit or another event causes it to resume. The init and destroy methods are not shown above because they are identical to the Tomcat version. This servlet uses the same MessageSender as the Tomcat version. No modification is needed. Notice how the begin method creates a Weatherman instance. That class is also used exactly as in the Tomcat version. Even the client code is identical. Only the servlet is changed at all. Its changes are significant, but with a straightforward mapping back to the event model in Tomcat.
I hope this is encouraging. The exact same code does not work in both Tomcat and Jetty, but it is very similar. Of course one of the appeals of JavaEE is portability. Most code that runs in Tomcat will run in Jetty with no modification and vice versa. Thus it should come as no surprise that the next version of the Java Servlet specification includes a standardization of asynchronous request processing, or, the underlying technology behind Comet. Let's take a look at that spec, the Servlet 3.0 spec. |
|