comet 推送 消息 聊天

来源:互联网 发布:epub 知乎 编辑:程序博客网 时间:2024/06/08 10:14

 

需要的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>();@Overridepublic 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的删除方法,否则可能会引发cuncurrentModifyExceptioniterator.remove();}}//最后关闭当前请求的CometEventevent.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" onclick="send();"/>    </form>      消息:    <div id="show"></div>  </body></html>

 

然后就可以打开多个浏览器测试了。。。