源地址链接: http://www.ibm.com/developerworks/cn/web/wa-cometjava/
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
public class TomcatWeatherServlet extends HttpServlet implements CometProcessor {
private MessageSender messageSender = null;
private static final Integer TIMEOUT = 60 * 1000;
@Override
public void destroy() {
log("destroy()!!!");
messageSender.stop();
messageSender = null;
}
@Override
public void init() throws ServletException {
log("init()!!!");
messageSender = new MessageSender();
Thread messageSenderThread =
new Thread(messageSender, "MessageSender[" + getServletContext().getContextPath() + "]");
messageSenderThread.setDaemon(true);
messageSenderThread.start();
}
public void event(final CometEvent event) throws IOException, ServletException {
HttpServletRequest request = event.getHttpServletRequest();
HttpServletResponse response = event.getHttpServletResponse();
if (event.getEventType() == CometEvent.EventType.BEGIN) {
request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
log("Begin for session: " + request.getSession(true).getId());
messageSender.setConnection(response);
Weatherman weatherman = new Weatherman(95118, 32408);
weatherman.start();
} else if (event.getEventType() == CometEvent.EventType.ERROR) {
log("Error for session: " + request.getSession(true).getId());
event.close();
} else if (event.getEventType() == CometEvent.EventType.END) {
log("End for session: " + request.getSession(true).getId());
event.close();
} else if (event.getEventType() == CometEvent.EventType.READ) {
throw new UnsupportedOperationException("This servlet does not accept data");
}
}
private class Weatherman {
private final List<URL> zipCodes;
private final String YAHOO_WEATHER = "http://weather.yahooapis.com/forecastrss?p=";
public Weatherman(Integer... zips) {
zipCodes = new ArrayList<URL>(zips.length);
for (Integer zip : zips) {
try {
zipCodes.add(new URL(YAHOO_WEATHER + zip));
} catch (Exception e) {
// dont add it if it sucks
}
}
}
public void start() {
Runnable r = new Runnable() {
public void run() {
int i = 0;
while (i >= 0) {
int j = i % zipCodes.size();
SyndFeedInput input = new SyndFeedInput();
try {
SyndFeed feed = input.build(new InputStreamReader(zipCodes.get(j).openStream()));
SyndEntry entry = (SyndEntry) feed.getEntries().get(0);
messageSender.send(entryToHtml(entry));
Thread.sleep(30000L);
} catch (Exception e) {
// just eat it, eat it
}
i++;
}
}
};
Thread t = new Thread(r);
t.start();
}
private String entryToHtml(SyndEntry entry){
StringBuilder html = new StringBuilder("<h2>");
html.append(entry.getTitle());
html.append("</h2>");
html.append(entry.getDescription().getValue());
return html.toString();
}
}
private class MessageSender implements Runnable {
protected boolean running = true;
protected final ArrayList<String> messages = new ArrayList<String>();
private ServletResponse connection;
private synchronized void setConnection(ServletResponse connection){
this.connection = connection;
notify();
}
public void stop() {
running = false;
}
/**
* Add message for sending.
*/
public void send(String message) {
synchronized (messages) {
messages.add(message);
log("Message added #messages=" + messages.size());
messages.notify();
}
}
public void run() {
log("start running!!!");
while (running) {
if (messages.size() == 0) {
try {
synchronized (messages) {
log("start waiting!!!");
messages.wait();
}
} catch (InterruptedException e) {
// Ignore
}
}
String[] pendingMessages = null;
synchronized (messages) {
pendingMessages = messages.toArray(new String[0]);
messages.clear();
}
try {
if (connection == null){
try{
synchronized(this){
wait();
}
} catch (InterruptedException e){
// Ignore
}
}
PrintWriter writer = connection.getWriter();
for (int j = 0; j < pendingMessages.length; j++) {
final String forecast = pendingMessages[j] + "<br>";
writer.println(forecast);
log("Writing:" + forecast);
}
writer.flush();
writer.close();
//connection = null;
log("Closing connection");
} catch (IOException e) {
log("IOExeption sending message", e);
}
}
}
}
}
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Comet Weather</title>
<SCRIPT TYPE="text/javascript">
function go(){
var url = "http://localhost:8080/comet1/Weather";
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.setRequestHeader("Content-Type","application/x-javascript;");
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200){
if (request.responseText) {
document.getElementById("forecasts").innerHTML = request.responseText;
}
}else{
document.getElementById("forecasts").innerHTML = "Error!!!!";
}
//go();
}
};
request.send(null);
}
</SCRIPT>
</head>
<body>
<h1>Rapid Fire Weather</h1>
<input type="button" onclick="go()" value="Go!"></input>
<div id="forecasts">
</div>
</body>
</html>
做如下修改:
一、JSP页面中客户端多次调用go(),改为一次,把循环调用go()语句注释掉。
二、每次request只有一次write,在MessageSender中注释掉 connection = null; 这样保证每次request有多次response。
Tomcat上说明Comet的模型是“BEGIN -> READ -> READ -> READ -> ERROR/TIMEOUT”,这里使用的get请求,不是post请求,没有使用到Read事件。
分享到:
相关推荐
tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不...
Comet的核心理念是通过长时间保持一个HTTP连接来实现服务器到客户端的数据推送,而不是每次有新数据时都创建新的连接。这种模式大大减少了网络开销,提高了大规模实时应用的性能。常见的Comet实现技术包括HTTP流、...
标题"asp.net comet例子"指的是一个展示如何在ASP.NET环境中实现Comet技术的实际示例。这个例子可能包含了一个服务端页面(Service.aspx和服务.aspx.cs),以及一个客户端的HTML页面(ajax.html)。服务端页面处理与...
Comet实现聊天室 运行时请将Tomcat的server.xml文件内的 connectionTimeout="20000" redirectPort="8443" /> 改为 connectionTimeout="20000" redirectPort="8443" /> 登陆的时候请记得先修改index.jsp...
Comet4j是一个Java框架,专门用于实现Comet技术,这是一种服务器推送技术,允许服务器向客户端实时推送数据,而不仅仅是响应客户端的请求。在Web应用中,这种技术常用于实现聊天、实时通知、股票更新等功能,它克服...
这个"comet demo"是一个展示如何在Java环境下利用Tomcat服务器实现Comet技术的实例。Tomcat 6.0是Apache软件基金会开发的开源Servlet容器,支持各种Java Web应用的部署,包括Comet技术。 首先,Comet的核心在于保持...
这是我做的一个comet应用的小例子,使用tomcat 6实现的,例子只能在FireFox上运行,运行时打开两个浏览器就能达到你要的效果了,还要记住把conf/server中的连接类型改为NIO protocol="org.apache.coyote....
总结来说,"Tomcat+Comet实现终端与服务端同步的小例子"是一个学习实时通信和服务器推送技术的好起点。通过这个例子,开发者可以了解如何利用现有Web服务器的特性,创建高效、实时的Web应用。同时,这也是对传统HTTP...
3. **Pushlet**:Pushlet是一个开源的Java库,它是Comet技术的一个实现。Pushlet使用了Servlet API,通过HTTP长连接来实现服务器到客户端的实时数据推送。Pushlet服务器端处理来自客户端的连接,当有新数据可用时,...
comet两种实现之一的ajax实现,内部有源代码,这是一个聊天室的例子
本文将深入探讨如何在Tomcat中开发一个Comet实例,这是一项用于实现服务器向客户端推送数据的技术,对于实时交互应用如聊天、股票更新或天气预报等场景非常关键。 Comet是一种持久连接技术,它打破了传统的HTTP请求...
在这个例子中,我们将学习如何构建一个基于DWR和Comet的网页聊天室,利用Spring来处理业务逻辑和控制流程。首先,我们需要在项目中集成DWR和Spring。这通常包括在`pom.xml`或`build.gradle`文件中添加相应的依赖,...
Comet4j是一个Java库,专门用于实现Comet技术,这是一种服务器推送技术,允许服务器向客户端实时推送数据,而不仅仅是响应客户端的请求。在Web应用中,这种技术常用于实现聊天室、股票报价、在线游戏等实时交互功能...
javaweb消息推送 基于comet实现局域网内部通讯(聊天室)demo 功能特性 推送消息广播。 推送定向消息。 提供连接上线前、上线、下线前、下线、发送消息等多种可处理事件。 消息缓存机制,确保长轮询工作模式下不丢失...
一个comet的实例,使用了dojoJavaScript等
总之,这个项目展示了如何结合Spring、DWR和Comet技术构建一个实时的多人聊天室。通过这样的实践,开发者可以深入理解Web实时通信的原理,同时掌握前后端分离、异步通信以及服务器推送等现代Web开发的关键技术。
在这个例子中,我们设置了"Content-Type"为"text/event-stream",这样浏览器会知道这是一个Server-Sent Events(SSE)流。我们还设置了"Cache-Control"和"Connection"头来保持连接开放。然后,在一个无限循环中,...
在压缩包文件`CometTest`中,可能包含了一个简单的Comet实现示例,你可以通过学习和运行这个例子来深入理解Servlet3.0异步处理和Comet页面推送的工作原理。通过实践,你可以更好地掌握如何在实际项目中利用这些技术...
描述中提到的是"服务器推送技术(server push)的一个实现demo",意味着这个项目提供了Comet技术的具体示例,可以帮助开发者理解和学习如何在实际项目中应用Comet。通常,这样的demo会包含代码示例、服务器配置以及...