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

2014-11-24 01:40:16 · 作者: · 浏览: 4
d。如果需要生成或使用RSS 或Atom feed,这是一个非常有用的库。此外,这个代码中只有一个地方值得注意,那就是它产生另一个线程,用于每过30 秒钟发送一次天气数据。最后,我们再看一个地方:使用该servlet 的客户机代码。在这种情况下,一个简单的JSP 加上少量的java script 就足够了。清单5 显示了该代码。

清单5. 客户机Comet 代码

<%@page contentType="text/html" pageEncoding="UTF-8"%>

"http://www.w3.org/TR/html4/loose.dtd">

Comet Weather

<SCRIPT TYPE="text/java script">

function go(){

var url = "http://localhost:8484/WeatherServer/Weather"

var request = new XMLHttpRequest();

request.open("GET", url, true);

request.setRequestHeader("Content-Type","application/x-java script;");

request.onreadystatechange = function() {

if (request.readyState == 4) {

if (request.status == 200){

if (request.responseText) {

document.getElementById("forecasts").innerHTML =

request.responseText;

}

}

go();

}

};

request.send(null);

}

Rapid Fire Weather

该代码只是在用户单击Go 按钮时开始长轮询。注意,它直接使用XMLHttpRequest 对象,所以这在Internet Explorer 6 中将不能工作。您可能需要使用一个Ajax 库解决浏览器差异问题。除此之外,惟一需要注意的是回调函数,或者为请求的onreadystatechange 函数创建的闭包。该函数粘贴来自服务器的新的数据,然后重新调用go 函数。

现在,我们看过了一个简单的Comet 应用程序在Tomcat 上是什么样的。有两件与Tomcat 密切相关的事情要做:一是配置它的连接器,二是在servlet 中实现一个特定于Tomcat 的接口。您可能想知道,将该代码 “移植” 到Jetty 有多大难度。接下来我们就来看看这个问题。

Jetty 和Comet

Jetty 服务器使用稍微不同的技术来支持Comet 的可伸缩的实现。Jetty 支持被称作continuations 的编程结构。其思想很简单。请求先被暂停,然后在将来的某个时间点再继续。规定时间到期,或者某种有意义的事件发生,都可能导致请求继续。当请求被暂停时,它的线程被释放。

可以使用Jetty 的org.mortbay.util.ajax.ContinuationSupport 类为任何HttpServletRequest 创建org.mortbay.util.ajax.Continuation 的一个实例。这种方法与Comet 有很大的不同。但是,continuations 可用于实现逻辑上等效的Comet。清单6 显示清单2 中的weather servlet “移植” 到Jetty 后的代码。

清单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 Unsupported