使用Java实现Comet风格的Web应用(六)

2014-11-24 01:40:16 · 作者: · 浏览: 3
OperationException();

}

@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));

}

}

这里最需要注意的是,该结构与Tomcat 版本的代码非常类似。begin、read、end 和error 方法都与Tomcat 中相同的事件匹配。该servlet 的service 方法被覆盖为在请求第一次进入时创建一个continuation 并暂停该请求,直到超时时间已到,或者发生导致它重新开始的事件。上面没有显示init 和destroy 方法,因为它们与Tomcat 版本是一样的。该servlet 使用与Tomcat 相同的MessageSender。因此不需要修改。注意begin 方法如何创建Weatherman 实例。对这个类的使用与Tomcat 版本中也是完全相同的。甚至客户机代码也是一样的。只有servlet 有更改。虽然servlet 的变化比较大,但是与Tomcat 中的事件模型仍是一一对应的。

希望这足以鼓舞人心。虽然完全相同的代码不能同时在Tomcat 和Jetty 中运行,但是它是非常相似的。当然,JavaEE 吸引人的一点是可移植性。大多数在Tomcat 中运行的代码,无需修改就可以在Jetty 中运行,反之亦然。因此,毫不奇怪,下一个版本的Java Servlet 规范包括异步请求处理(即Comet 背后的底层技术)的标准化。 我们来看看这个规范:Servlet 3.0 规范。

回页首

Servlet 3.0 规范

在此,我们不深究Servlet 3.0 规范的全部细节,只看看Comet servlet 如果在Servlet 3.0 容器中运行,可能会是什么样子。注意 “可能” 二字。该规范已经发布公共预览版,但在撰写本文之际,还没有最终版。因此,清单7 显示的是遵从公共预览规范的一个实现。

清单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);;

}

}

值得高兴的是,这个版本要简单得多。平心而论,如果不遵从Tomcat 的事件模型,在Jetty 中可以有类似的实现。这种事件模型似乎比较合理,很容易在Tomcat 以外的容器(例如Jetty)中实现,只是没有相关的标准。

回头看看清单7,注意它的标注声明它支持异步处理,并设置了超时时间。startAsync 方法是HttpServletRequest 上的一个新方法,它返回新的javax.servlet.AsyncContext 类的一个实例。注意,MessageSender 现在传递AsynContext 的引用,而不是ServletResponse 的引用。在这里,不应该关闭响应,而是调用AsyncContext 实例上的complete 方法。还应注意,Weatherman 被直接传递到AsyncContext 实例的start 方法。这样将在当前ServletContext 中开始一个新线程。

而且,尽管与Tomcat 或Jetty 相比都有较大的不同,但是修改相同风格的编程来处理Servlet 3.0 规范提议的API 并不是太难。还应注意,Jetty 7 是为实现Servlet 3.0 而设计的,目前处于beta 状态。但是,在撰写本文之际,它还没有实现该规范的最新版本。

回页首

结束语

Comet 风格的Web 应用程序可以为Web 带来全新的交互性。它为大规模地实现这些特性带来一些复杂的挑战。但是,领先的Java Web 服务器正在为实现Comet 提供成熟、稳定的技术。在本文中,您看到了Tomcat 和Jetty 上当前风格的Comet 的不同点和相似点,以及正在进行的Servlet 3.0 规范的标准化。Tomcat 和Jetty 使如今构建可伸缩的Comet 应用程序成为可能,并且明确了未来面向Servlet 3.0 标准化的升级路线。

回页首

下载描述 名字 大小 下载方法

Weather Server 源代码WeatherServer.zip 347KB HTTP

关于下载方法的信息

参考资料

学习

“Comet 的诱惑”:发现更多关于Comet 背后的历史和动机的信息。

“通过Tomcat Advanced I/