12
返回列表 发新帖
楼主: Sky-Tiger

Developing with Comet and Java

[复制链接]
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
11#
 楼主| 发表于 2009-6-2 22:15 | 只看该作者
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.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
12#
 楼主| 发表于 2009-6-2 22:15 | 只看该作者
Servlet 3.0 spec

We could dive into all of the gnarly details of the Servlet 3.0 specification. Instead let's just take a look at what the Comet servlet might look like if it was running inside a Servlet 3.0 container. Notice the word "might." The specification has been released for public review, but has not been finalized as of the time of this writing. Thus Listing 7 shows an implementation compliant with the public review specification.

Listing 7. Servlet 3.0 Comet

@WebServlet(asyncSupported=true, asyncTimeout=5000)
public class WeatherServlet extends HttpServlet {
   private MessageSender messageSender;

// init and destroy are the same as other
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        AsyncContext async = request.startAsync(request, response);
        messageSender.setConnection(async);
        Weatherman weatherman = new Weatherman(95118, 32444);
        async.start(weatherman);;
    }
}


The nice thing here is that this is much simpler. In all fairness, a similar implementation is possible with Jetty, if we had not tried to adhere to the event model of Tomcat. The event model may have seemed sensible and could be easily implemented in containers other than Tomcat, like Jetty, but there will be no standardization around it.

Looking back at Listing 7, notice that its annotation declares that it supports asynchronous processing and sets the timeout. The startAsync method is a new method on HttpServletRequest, and it returns an instance of the new class javax.servlet.AsyncContext. Notice that the MessageSender is being passed a reference to the AsynContext instead of the ServletResponse. Instead of closing the response, you should call the complete method on the AsyncContext instance. Also notice that the Weatherman was passed directly to the start method of the AsyncContext instance. This starts a new thread in the current ServletContext.

So, despite being significantly different than either Tomcat or Jetty, it is not too hard to adapt the same style of programming to work with the proposed APIs of the Servlet 3.0 specification. It should be noted that Jetty 7 is intended to implement Servlet 3.0 and is available in a beta form. However, as of the time of writing, it did not implement the latest version of the specification as shown above.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
13#
 楼主| 发表于 2009-6-2 22:15 | 只看该作者
Summary

Comet-style Web applications can bring a whole new level of interactivity to the Web. It presents some complex challenges for implementing these features on a large scale. However, the leading Java Web servers are all providing mature, stable technology for implementing Comet. You have seen in this article the differences and similarities of the current flavors of Comet on Tomcat and Jetty, as well as the ongoing standardization effort for the Servlet 3.0 specification. Tomcat and Jetty make it possible to build scalable Comet applications today, with a clear upgrade path to standardization under Servlet 3.0 in the future.

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表