Tomcat已经实现了自己的comet方式,并且提供了一个例子。这样网上的例子很多,我精简了些。
MessageSender.java
package me.comet;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import javax.servlet.ServletResponse;
public class MessageSender extends Thread {
private ServletResponse connection;
public MessageSender(ServletResponse connection) {
this.connection = connection;
}
public void run() {
try {
while (true) {
if (connection == null) {
synchronized (this) {
wait();
}
}
OutputStream out = connection.getOutputStream();
out.write(getString().getBytes());
out.flush();
connection.flushBuffer();
System.out.print(getString());
Thread.sleep(1000);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
private String getString() {
return Thread.currentThread()+" CurrentTime "+new Date().toLocaleString() + "\n";
}
}
TimeServlet.java
package me.comet;
import java.io.IOException;
import javax.servlet.ServletException;
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;
public class TimeServlet extends HttpServlet implements CometProcessor {
private static final long serialVersionUID = 1L;
private static final Integer TIMEOUT = 10 * 1000;
private MessageSender sender = null;
public void event(CometEvent event) throws IOException, ServletException {
HttpServletRequest request = event.getHttpServletRequest();
HttpServletResponse response = event.getHttpServletResponse();
if (event.getEventType() == CometEvent.EventType.BEGIN) {
log("Begin for session: " + request.getSession(true).getId());
request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
sender = new MessageSender(response);
sender.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");
}
}
@Override
public void destroy() {
sender.interrupt();
sender = null;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>TimeServlet</servlet-name>
<servlet-class>me.comet.TimeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TimeServlet</servlet-name>
<url-pattern>/time</url-pattern>
</servlet-mapping>
</web-app>
test.jsp
<%@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>
</head>
<body>
<label>记录</label>
<br/>
<iframe src="http://localhost:8080/comet/time"
width="60%" height="300" frameborder="1"></iframe>
</body>
</html>
更改 tomcat/conf/server.xml
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />
更改 tomcat/conf/context.xml
<Context>
<Loader delegate="true" />
<WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>
jar包
添加tomcat/lib/catalina.jar