需要的jar包以及基础的配置参考:
tomcat comet 推送 技术 入门
直接切入正题:
首先引入tomcat的lib目录下的jar包:
catalina.jar,servlet-api.jar
另外要修改tomcat的server.xml,将protocal="http/1.1"什么的修改为:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />
这样就让tomcat支持推送功能了
首先是servlet(带有注释):
package nio.comet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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 ChatCometServlet extends HttpServlet implements CometProcessor{
private static final long serialVersionUID = 1L;
private List<CometEvent> events = new ArrayList<CometEvent>();
@Override
public void event(CometEvent event) throws IOException, ServletException {
HttpServletRequest request = event.getHttpServletRequest();
String path = request.getRequestURI();
if(path.indexOf("setComet") != -1){
//发送消息的请求
String message = request.getParameter("message");
//遍历所有的CometEvent,将消息发送出去
synchronized(events){
//使用list的遍历器
Iterator<CometEvent> iterator = events.iterator();
CometEvent e = null;
while(iterator.hasNext()){
e = iterator.next();
HttpServletResponse res = e.getHttpServletResponse();
//设置响应的编码和类型
res.setCharacterEncoding("utf-8");
res.setContentType("text/plain");
PrintWriter writer = res.getWriter();
writer.write(message);
writer.flush();
//一定要调用list保存的CometEvent对象的close方法关闭,这样才可以及时将消息推送出去
e.close();
//删除的时候要使用iterator的删除方法,否则可能会引发cuncurrentModifyException
iterator.remove();
}
}
//最后关闭当前请求的CometEvent
event.close();
return;
}else if(path.indexOf("getComet") != -1){
//获取消息的请求
if(event.getEventType() == CometEvent.EventType.BEGIN){
//begin阶段,设置超时时间,并将CometEvent对于保存到list中,其他阶段均返回ERROR(简单处理)
event.setTimeout(20000);
synchronized(events){
events.add(event);
}
return;
}else if(event.getEventType() == CometEvent.EventType.END){
synchronized(events){
HttpServletResponse res = event.getHttpServletResponse();
res.setCharacterEncoding("utf-8");
res.setContentType("text/plain");
PrintWriter writer = res.getWriter();
writer.write("ERROR");
writer.flush();
event.close();
events.remove(event);
}
return;
}else if(event.getEventType() == CometEvent.EventType.ERROR){
synchronized(events){
HttpServletResponse res = event.getHttpServletResponse();
res.setCharacterEncoding("utf-8");
res.setContentType("text/plain");
PrintWriter writer = res.getWriter();
writer.write("ERROR");
writer.flush();
event.close();
events.remove(event);
}
return;
}else if(event.getEventType() == CometEvent.EventType.READ){
synchronized(events){
HttpServletResponse res = event.getHttpServletResponse();
res.setCharacterEncoding("utf-8");
res.setContentType("text/plain");
PrintWriter writer = res.getWriter();
writer.write("ERROR");
writer.flush();
event.close();
events.remove(event);
}
return;
}
}
}
}
然后再web.xml中配置servlet:
<servlet> <servlet-name>mycomet</servlet-name> <servlet-class>nio.comet.ChatCometServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>mycomet</servlet-name> <url-pattern>/comet/*</url-pattern> </servlet-mapping>
然后就是页面了(里面需要引入jquery):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'chat.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript" src="upload/js/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
//页面加载完之后就发起读取消息的长连接
read();
});
//发送消息
function send(){
var f = document.forms['cometForm'];
$.post("comet/setComet",$(f).serialize());
}
//读取消息
function read(){
$.ajax({
type: "POST",
url: "comet/getComet",
success: function(data){
if("ERROR" != data){
$("#show").html($("#show").html()+'<br/>'+data);
}
read();
}
});
}
</script>
</head>
<body>
<form name="cometForm">
<input type="text" name="message"/>
<input type="button" value="send" οnclick="send();"/>
</form>
消息:
<div id="show"></div>
</body>
</html>
然后就可以打开多个浏览器测试了。。。