文章分类:Web前端
<%@ page language="java" contentType="text/html; charset=UTF-8" 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"> <script type="text/javascript" src="jquery-1.4.2.min.js"></script> <link rel="stylesheet" href="960.css" /> <title>Comet Chat Demo</title> <script type="text/javascript"> var server = 'http://localhost:8080/CometDemo/ChatComet?name=<%=request.getParameter("name")%>'; var comet = { connection : false, iframediv : false, initialize: function() { if (navigator.appVersion.indexOf("MSIE") != -1) { comet.connection = new ActiveXObject("htmlfile"); comet.connection.open(); comet.connection.write("<html>"); comet.connection.write("<script>document.domain = '"+document.domain+"'"); comet.connection.write("</html>"); comet.connection.close(); comet.iframediv = comet.connection.createElement("div"); comet.connection.appendChild(comet.iframediv); comet.connection.parentWindow.comet = comet; comet.iframediv.innerHTML = "<iframe id='comet_iframe' src='"+server+"'></iframe>"; } else if (navigator.appVersion.indexOf("KHTML") != -1) { comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); comet.connection.setAttribute('src', server); with (comet.connection.style) { position = "absolute"; left = top = "-100px"; height = width = "1px"; visibility = "hidden"; } document.body.appendChild(comet.connection); } else { comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); with (comet.connection.style) { left = top = "-100px"; height = width = "1px"; visibility = "hidden"; display = 'none'; } comet.iframediv = document.createElement('iframe'); comet.iframediv.setAttribute('src', server); comet.connection.appendChild(comet.iframediv); document.body.appendChild(comet.connection); } }, //添加用户 newUser:function(data){ var list = document.getElementById('userList'); var li = document.createElement('li'); li.setAttribute("id","u1"+data); li.innerHTML = data; list.appendChild(li); var user = document.getElementById('user'); var option = document.createElement('option'); option.setAttribute("id","u2"+data); option.innerHTML = data; user.appendChild(option); }, //删除用户 deleteUser:function(data){ $('#u1'+data).remove(); $('#u2'+data).remove(); }, //添加公共消息 newMessage:function(data){ var list = document.getElementById('messageList'); var li = document.createElement('li'); li.innerHTML = data; list.appendChild(li); }, //添加私人消息 privateMessage:function(data){ var list = document.getElementById('privateMessage'); var li = document.createElement('li'); li.innerHTML = data; list.appendChild(li); }, //退出 onUnload: function() { if (comet.connection) { comet.connection = false; } } }//comet end if (window.addEventListener) { window.addEventListener("load", comet.initialize, false); window.addEventListener("unload", comet.onUnload, false); } else if (window.attachEvent) { window.attachEvent("onload", comet.initialize); window.attachEvent("onunload", comet.onUnload); } </script> </head> <body> <script type="text/javascript"> function sendAll(){ var list = document.getElementById('privateMessage'); var li = document.createElement('li'); li.innerHTML = "I said to "+$("#user").val()+": " + $("#message").val(); list.appendChild(li); $.ajax({ type: "POST", url: "MessageServlet", data: "message="+$("#message").val()+"&user="+$("#user").val()+"&from=<%=request.getParameter("name")%>" }); } </script> <div class="container_12"> <div class="grid_10"> <div>公共聊天</div> <div id="messageList" style="height:250px;overflow:scroll;border:solid 1px black;"> </div> <br/> <div>个人聊天</div> <div id="privateMessage" style="height:150px;overflow:scroll;border:solid 1px black;"> </div> <br/> <div> <select id="user" style="width:100px;overflow:scroll;"> <option value="all">All</option> </select> <input type="text" id="message" size="40"></input> <input type="button" value="发言" onclick="sendAll()"> </div> </div> <div class="grid_2"> <h3>用户列表</h3> <ol id="userList"> </ol> </div> </div> </body> </html>
package demo; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; 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; /** * * @author Aries Zhao * */ public class ChatServlet extends HttpServlet implements CometProcessor { private static final long serialVersionUID = -3667180332947986301L; // <用户,长连接> protected static Map<String, HttpServletResponse> connections = new HashMap<String, HttpServletResponse>(); // 消息推送线程 protected static MessageSender messageSender = null; public void init() throws ServletException { // 启动消息推送线程 messageSender = new MessageSender(); Thread messageSenderThread = new Thread(messageSender, "MessageSender[" + getServletContext().getContextPath() + "]"); messageSenderThread.setDaemon(true); messageSenderThread.start(); } public void destroy() { connections.clear(); messageSender.stop(); messageSender = null; } public void event(CometEvent event) throws IOException, ServletException { HttpServletRequest request = event.getHttpServletRequest(); HttpServletResponse response = event.getHttpServletResponse(); // 昵称 String name = request.getParameter("name"); if (name == null) { return; } if (event.getEventType() == CometEvent.EventType.BEGIN) { // Http连接空闲超时 event.setTimeout(Integer.MAX_VALUE); log("Begin for session: " + request.getSession(true).getId()); // 创建Comet Iframe PrintWriter writer = response.getWriter(); writer .println("<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">"); writer .println("<html><head><script type=\"text/javascript\">var comet = window.parent.comet;</script></head><body>"); writer.println("<script type=\"text/javascript\">"); writer.println("var comet = window.parent.comet;"); writer.println("</script>"); writer.flush(); // for chrome if (request.getHeader("User-Agent").contains("KHTML")) { for (int i = 0; i < 100; i++) { writer.print("<input type=hidden name=none value=none>"); } writer.flush(); } // 欢迎信息 writer.print("<script type=\"text/javascript\">"); writer.println("comet.newMessage('Hello " + name + ", Welcome!');"); writer.print("</script>"); writer.flush(); // 通知其他用户有新用户登陆 if (!connections.containsKey(name)) { messageSender.login(name); } // 推送已经登陆的用户信息 for (String user : connections.keySet()) { if (!user.equals(name)) { writer.print("<script type=\"text/javascript\">"); writer.println("comet.newUser('" + user + "');"); writer.print("</script>"); } } writer.flush(); synchronized (connections) { connections.put(name, response); } } else if (event.getEventType() == CometEvent.EventType.ERROR) { log("Error for session: " + request.getSession(true).getId()); synchronized (connections) { connections.remove(name); } event.close(); } else if (event.getEventType() == CometEvent.EventType.END) { log("End for session: " + request.getSession(true).getId()); messageSender.logout(name); synchronized (connections) { connections.remove(name); } PrintWriter writer = response.getWriter(); writer.println("</body></html>"); event.close(); } else if (event.getEventType() == CometEvent.EventType.READ) { InputStream is = request.getInputStream(); byte[] buf = new byte[512]; do { int n = is.read(buf); // can throw an IOException if (n > 0) { log("Read " + n + " bytes: " + new String(buf, 0, n) + " for session: " + request.getSession(true).getId()); } else if (n < 0) { return; } } while (is.available() > 0); } } // 发送消息给所有人 public static void send(String message) { messageSender.send("*", message); } // 向某个连接发送消息 public static void send(String name, String message) { messageSender.send(name, message); } public class MessageSender implements Runnable { protected boolean running = true; protected Map<String, String> messages = new HashMap<String, String>(); public MessageSender() { } public void stop() { running = false; } // 新用户登陆 public void login(String name) { synchronized (messages) { messages.put("Login", name); messages.notify(); } } // 用户下线 public void logout(String name) { synchronized (messages) { messages.put("Logout", name); messages.notify(); } } // 发送消息 public void send(String user, String message) { synchronized (messages) { messages.put(user, message); messages.notify(); } } public void run() { while (running) { if (messages.size() == 0) { try { synchronized (messages) { messages.wait(); } } catch (InterruptedException e) { // Ignore } } synchronized (connections) { synchronized (messages) { // 推送消息队列中的消息 for (Entry<String, String> message : messages .entrySet()) { if (message.getKey().equals("Login")) {// 新用户登陆 log(message.getValue() + " Login"); for (HttpServletResponse response : connections .values()) { try { PrintWriter writer = response .getWriter(); writer .print("<script type=\"text/javascript\">"); writer .println("comet.newMessage('Welcome " + message.getValue() + " !');"); writer.println("comet.newUser('" + message.getValue() + "');"); writer.print("</script>"); writer.flush(); } catch (IOException e) { log("IOExeption execute command", e); } } } else if ("Logout".equals(message.getKey())) {// 用户退出 log(message.getValue() + " Logout"); for (HttpServletResponse response : connections .values()) { try { PrintWriter writer = response .getWriter(); writer转载自:http://a
评论