comet 推送 消息 聊天

 

需要的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" onclick="send();"/>
    </form>
      消息:
    <div id="show"></div>
  </body>
</html>

 

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

 

 

你可能感兴趣的:(推送,聊天,Comet,消息)