`
huibin
  • 浏览: 757149 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

Comet基于iframe的服务器推送(Server Push)例子

阅读更多

服务器推送技术(Server Push)是最近Web技术中最热门的一个流行术语,它的别名叫Comet(彗星)。它是继AJAX之后又一个倍受追捧的Web技术。Comet有时也称反向 Ajax 或服务器端推技术(server-side push)。其思想很简单:将数据直接从服务器推到浏览器,而不必等到浏览器请求数据。听起来简单,但是如果熟悉 Web 应用 程序,尤其是 HTTP 协议,那么您就会知道,这绝不简单。实现 Comet 风格的 Web 应用程序,同时保证在浏览器和服务器上的可伸缩性,这只是在最近几年才成为可能。目前一些主流网站都有类似的原理,例如:webQQ、开心网、白社会等等,它们中消息动态都是采用类似的技术,也许具体实现方式不一样。目前大概有三种实现方式:基于长轮询(long polling)、基于iframe“、基于流(stream)三种实现comet的方式。
     下面是在Tomcat6.x的基础上实现基于iframe的comet聊天室:


index.jsp:聊天室页面
ChatServlet.java:实现了长连接的Servlet
MessageServlet.java:消息接受Servert


     仅仅是一个Demo,可以从index.jsp?name=yourNickName进入,实现了上线,下线通知,群发,消息功能,性能还没有测试...
     目前能够正常在IE,FireFox和Chrome下正常运行,但在Chrome下会一直加载不完,不知道有没有办法解决?还有不知道能不能在此基础之上搞一个基于iframe的Comet工具,包括前台js和后台java.

      首先修改Tomcat配置文件
      修改server.xml中<Connector connectionTimeout="20000" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol " redirectPort="8443"/>,底层用NIO实现的Http连接器

index.jsp

view plaincopy to clipboardprint?
     <%@ 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">  
<mce:script type="text/javascript" src="jquery-1.4.2.min.js" mce_src="jquery-1.4.2.min.js"></mce:script>  
<link rel="stylesheet" href="960.css" mce_href="960.css" />  
<title>Comet Chat Demo</title>  
<mce: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+"" mce_src="&quot;+server+&quot;"></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);  
}  
// --></mce:script>  
</head>  
<body>  
<mce: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")%>" 
     });  
}  
// --></mce: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>  
     <%@ 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">
<mce:script type="text/javascript" src="jquery-1.4.2.min.js" mce_src="jquery-1.4.2.min.js"></mce:script>
<link rel="stylesheet" href="960.css" mce_href="960.css" />
<title>Comet Chat Demo</title>
<mce: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+"" mce_src="&quot;+server+&quot;"></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);
}
// --></mce:script>
</head>
<body>
<mce: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")%>"
  });
}
// --></mce: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> 

ChatServlet.java

view plaincopy to clipboardprint?
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><mce:script type=\"text/javascript\"><!--  
var comet = window.parent.comet;  
// --></mce:script></head><body>");  
            writer.println("<mce:script type=\"text/javascript\"><!--  
");  
            writer.println("var comet = window.parent.comet;");  
            writer.println("  
// --></mce: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("<mce:script type=\"text/javascript\"><!--  
");  
            writer.println("comet.newMessage('Hello " + name + ", Welcome!');");  
            writer.print("  
// --></mce:script>");  
            writer.flush();  
            // 通知其他用户有新用户登陆  
            if (!connections.containsKey(name)) {  
                messageSender.login(name);  
            }  
            // 推送已经登陆的用户信息  
            for (String user : connections.keySet()) {  
                if (!user.equals(name)) {  
                    writer.print("<mce:script type=\"text/javascript\"><!--  
");  
                    writer.println("comet.newUser('" + user + "');");  
                    writer.print("  
// --></mce: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("<mce:script type=\"text/javascript\"><!--  
");  
                                        writer  
                                                .println("comet.newMessage('Welcome " 
                                                        + message.getValue()  
                                                        + " !');");  
                                        writer.println("comet.newUser('" 
                                                + message.getValue() + "');");  
                                        writer.print("  
// --></mce: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  
                                                .print("<mce:script type=\"text/javascript\"><!--  
");  
                                        writer.println("comet.newMessage('88, " 
                                                + message.getValue() + "');");  
                                        writer.println("comet.deleteUser('" 
                                                + message.getValue() + "');");  
                                        writer.print("  
// --></mce:script>");  
                                        writer.flush();  
                                    } catch (IOException e) {  
                                        log("IOExeption execute command", e);  
                                    }  
                                }  
                            } else if ("*".equals(message.getKey())) {// 群发消息  
                                log("Send message: " + message.getValue()  
                                        + " to everyone.");  
                                for (HttpServletResponse response : connections  
                                        .values()) {  
                                    try {  
                                        PrintWriter writer = response  
                                                .getWriter();  
                                        writer  
                                                .print("<mce:script type=\"text/javascript\"><!--  
");  
                                        writer.println("comet.newMessage('" 
                                                + message.getValue() + "');");  
                                        writer.print("  
// --></mce:script>");  
                                        writer.flush();  
                                    } catch (IOException e) {  
                                        log("IOExeption execute command", e);  
                                    }  
                                }  
                            } else {// 向某人发信息  
                                try {  
                                    HttpServletResponse response = connections  
                                            .get(message.getKey());  
                                    PrintWriter writer = response.getWriter();  
                                    writer  
                                            .print("<mce:script type=\"text/javascript\"><!--  
");  
                                    writer.println("comet.privateMessage('" 
                                            + message.getValue() + "');");  
                                    writer.print("  
// --></mce:script>");  
                                    writer.flush();  
                                } catch (IOException e) {  
                                    log("IOExeption sending message", e);  
                                }  
                            }  
                            // 从消息队列中删除消息  
                            messages.remove(message.getKey());  
                        }  
                    }  
                }  
            }  
        }  
    }  

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><mce:script type=\"text/javascript\"><!--
var comet = window.parent.comet;
// --></mce:script></head><body>");
   writer.println("<mce:script type=\"text/javascript\"><!--
");
   writer.println("var comet = window.parent.comet;");
   writer.println("
// --></mce: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("<mce:script type=\"text/javascript\"><!--
");
   writer.println("comet.newMessage('Hello " + name + ", Welcome!');");
   writer.print("
// --></mce:script>");
   writer.flush();
   // 通知其他用户有新用户登陆
   if (!connections.containsKey(name)) {
    messageSender.login(name);
   }
   // 推送已经登陆的用户信息
   for (String user : connections.keySet()) {
    if (!user.equals(name)) {
     writer.print("<mce:script type=\"text/javascript\"><!--
");
     writer.println("comet.newUser('" + user + "');");
     writer.print("
// --></mce: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("<mce:script type=\"text/javascript\"><!--
");
          writer
            .println("comet.newMessage('Welcome "
              + message.getValue()
              + " !');");
          writer.println("comet.newUser('"
            + message.getValue() + "');");
          writer.print("
// --></mce: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
            .print("<mce:script type=\"text/javascript\"><!--
");
          writer.println("comet.newMessage('88, "
            + message.getValue() + "');");
          writer.println("comet.deleteUser('"
            + message.getValue() + "');");
          writer.print("
// --></mce:script>");
          writer.flush();
         } catch (IOException e) {
          log("IOExeption execute command", e);
         }
        }
       } else if ("*".equals(message.getKey())) {// 群发消息
        log("Send message: " + message.getValue()
          + " to everyone.");
        for (HttpServletResponse response : connections
          .values()) {
         try {
          PrintWriter writer = response
            .getWriter();
          writer
            .print("<mce:script type=\"text/javascript\"><!--
");
          writer.println("comet.newMessage('"
            + message.getValue() + "');");
          writer.print("
// --></mce:script>");
          writer.flush();
         } catch (IOException e) {
          log("IOExeption execute command", e);
         }
        }
       } else {// 向某人发信息
        try {
         HttpServletResponse response = connections
           .get(message.getKey());
         PrintWriter writer = response.getWriter();
         writer
           .print("<mce:script type=\"text/javascript\"><!--
");
         writer.println("comet.privateMessage('"
           + message.getValue() + "');");
         writer.print("
// --></mce:script>");
         writer.flush();
        } catch (IOException e) {
         log("IOExeption sending message", e);
        }
       }
       // 从消息队列中删除消息
       messages.remove(message.getKey());
      }
     }
    }
   }
  }
 }
}
 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/buyaore_wo/archive/2011/02/07/6173777.aspx

分享到:
评论

相关推荐

    多种方式模拟服务器推送客户端

    在Web开发中,服务器向客户端实时推送数据是常见...在名为"serverPush"的压缩包文件中,可能包含了实现上述各种服务器推送方式的JAVA代码示例,开发者可以通过阅读和学习这些代码,进一步理解并掌握服务器推送的技术。

    web推送 comet技术

    Comet技术是一种基于HTTP长连接的Web实时通信技术,它允许服务器向客户端主动推送数据,而无需客户端发起新的请求。这种技术打破了传统的HTTP请求-响应模型,极大地提升了Web应用的实时性和交互性,尤其适用于股票...

    asp.net comet例子

    ASP.NET Comet是一个技术概念,它涉及到了Web应用程序中的实时通信,特别是服务器向客户端推送数据的能力。在传统的HTTP协议中,服务器通常在客户端发起请求时才响应,而在Comet模式下,服务器可以保持一个连接开放...

    PushMessage JavaWeb聊天 推送 实现

    3. **Comet技术**:Comet是长轮询的一种抽象,它包括了多种实现方式,如流、隐藏IFrame和JSONP等,目的是实现服务器到浏览器的推送。 4. **Servlet与WebSocket结合**:在JavaWeb应用中,CharServletPush可能表示一...

    comet demo

    "消息推送"是Comet的核心特性,服务器能够主动将新的消息推送给客户端,无需客户端频繁地轮询请求,从而提高了效率并降低了服务器压力。 Comet技术通常有几种实现方式,包括长轮询(Long Polling)、iframe、流...

    asp.net 消息推送

    ASP.NET 消息推送技术是Web开发中的一个重要概念,它允许服务器主动向客户端发送数据,而无需客户端(如浏览器)不断地发起请求。这种技术在实时性要求高的应用场景中非常关键,比如聊天应用、股票更新、在线游戏等...

    pushlet 和comet 资料介绍

    Pushlet和Comet技术是Web服务器向浏览器推送数据的两种策略,主要用于实现实时的、双向的通信。这两种技术在传统的HTTP协议基础上进行了扩展,克服了HTTP请求-响应模型的限制,使得服务器能够主动向客户端推送数据,...

    论文研究-一个基于push技术的web实时网络管理框架 .pdf

    服务器可以不断地向这个隐藏的IFrame推送数据,而JavaScript则可以处理这些数据并更新主页面。这种方式可以持续不断地更新信息,而不会被浏览器关闭或网络异常打断。 知识点五:TMN管理模型与实时网络管理框架的...

    使用nodejs搭建最简单的comet原型参考.pdf

    Comet是一种基于HTTP长连接的服务器推送技术,旨在提供实时的Web应用程序交互。它与AJAX类似,但不同之处在于,AJAX通常依赖于短连接和异步请求,而Comet则保持一个开放的HTTP连接,允许服务器主动向客户端推送数据...

    网易邮箱的Comet实践_陈志凌(网易)

    网易邮箱使用Comet技术来实现其Webim(邮箱聊天)和Pushmail(邮件推送)等项目。这些项目需要实时更新和即时推送信息给用户,因此选择Comet作为技术支持。 5. 如何选择适合的方案: 当选择适合的Comet实现方案时...

    dwr反推demo

    DWR2.x版本引入了反推(Reverse Ajax)技术,也被称为服务器端推送(Server-Side Push),它打破了传统Ajax模式中由客户端发起请求、服务器响应的单向通信模式,实现了服务器端可以主动将数据推送到客户端的功能。...

    AJAX项目开发指南

    - **使用Server Push技术**:例如Comet技术,可以让服务器主动推送数据到客户端。 - **选择合适的框架**:根据项目需求选择合适的框架,如DWR、Dojo Toolkit等。 ##### 3.2 实现案例 - **即时股市报价**:可以采用...

    SD大会精品讲座:利用AJAX/Java 技术建立高流量的即时双向沟通网站

    - **Comet**:一种实现Server Push的技术,通过对HTTP连接的长期保持来实现服务器向客户端推送数据。 - **WebSocket**:提供了全双工的通信通道,可以实现客户端和服务器之间的双向通信。 #### 六、应用实例 - ...

    PHP使用反向Ajax技术实现在线客服系统详解

    反向Ajax技术,又称为服务器推技术(server push),是一种允许服务器主动向客户端发送数据的技术。与传统Ajax技术的客户端拉数据(客户端通过定时向服务器发送请求来获取最新数据)不同,反向Ajax技术中,服务器能够...

Global site tag (gtag.js) - Google Analytics