• 基于AJAX的长轮询(longpolling)方式实现简单的聊天室程序


    基于AJAX的长轮询(long-polling)方式实现简单的聊天室程序

    (转http://blog.csdn.net/neusoftware_20063500/archive/2009/04/30/4140903.aspx)

    这里只是做个测试,很简单,没有做好线程同步的问题,只是为了长轮询。

    原理:

    可以看:http://yiminghe.javaeye.com/blog/294781

    AJAX 的出现使得 JavaScript 可以调用 XMLHttpRequest 对象发出 HTTP 请求,JavaScript 响应处理函数根据服务器返回的信息对 HTML 页面的显示进行更新。使用 AJAX 实现“服务器推”与传统的 AJAX 应用不同之处在于:

    1. 服务器端会阻塞请求直到有数据传递或超时才返回。
    2. 客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
    3. 当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。

    聊天页面的代码:

    1. <%@ page language="java" pageEncoding="GBK"%>  
    2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    3. <html>  
    4.     <head>  
    5.         <title>chat room</title>  
    6.         <meta http-equiv="pragma" content="no-cache">  
    7.         <meta http-equiv="cache-control" content="no-cache">  
    8.         <meta http-equiv="expires" content="0">  
    9.         <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
    10.         <meta http-equiv="description" content="This is my page">  
    11.         <mce:script type="text/javascript" src="ext-2.2/adapter/ext/ext-base.js" mce_src="ext-2.2/adapter/ext/ext-base.js"></mce:script>  
    12.         <mce:script type="text/javascript" src="ext-2.2/ext-all.js" mce_src="ext-2.2/ext-all.js"></mce:script>  
    13.         <mce:script type="text/javascript"  
    14.             src="ext-2.2/build/locale/ext-lang-zh_CN.js"></mce:script>  
    15.         <mce:script type="text/javascript" src="jslib/mm.js" mce_src="jslib/mm.js"></mce:script>  
    16.     </head>  
    17.     <body>  
    18.         <div id="main"></div><!-- 显示聊天记录的区域 -->  
    19.         username:  
    20.         <input type="text" name="username" />  
    21.         <br>  
    22.         message:  
    23.         <input type="text" id="message">  
    24.         <br>  
    25.         <input type="button" value="submit" onclick="putMsg()">  
    26.     </body>  
    27. </html>  

    定义mm.js,定义发送消息,定义接收消息的JS函数

    1. Ext.onReady(function () {  
    2.     getMsg();  
    3. });  
    4. function getMsg() {  
    5.     Ext.Ajax.request({url:"getMsg", callback:function (options, success, response) {  
    6.         if (success) {  
    7.             Ext.DomHelper.append(Ext.get("main"), response.responseText, true);  
    8.         }  
    9.         getMsg();  
    10.     }});  
    11. }  
    12. function putMsg() {  
    13.     Ext.Ajax.request({url:"putMsg", params:{message:document.getElementById("message").value}});  
    14. }  
    15. /* 
    16. Ext.Updater.defaults.indicatorText='<div><img src="icon/loading.gif" mce_src="icon/loading.gif" width="20" height="20"/>refresh...</div>'; 
    17.     var updater = Ext.get('main').getUpdater(); 
    18.     updater.update({ 
    19.         url:"getMsg" 
    20.     }); 
    21. */  

     下面是获得message的servlet

    1. package hyjc.listener;  
    2.   
    3. import java.io.IOException;  
    4. import java.io.PrintWriter;  
    5.   
    6. import javax.servlet.ServletException;  
    7. import javax.servlet.http.HttpServlet;  
    8. import javax.servlet.http.HttpServletRequest;  
    9. import javax.servlet.http.HttpServletResponse;  
    10.   
    11. public class GetMsg extends HttpServlet {  
    12.   
    13.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
    14.             throws ServletException, IOException {  
    15.   
    16.         response.setContentType("text/html");  
    17.         PrintWriter out = response.getWriter();  
    18.         MessageList m = MessageList.getInstance();  
    19.         boolean end = false;  
    20.         while (!end) {  
    21.             System.out.println("before get");  
    22.             String msg = m.get();  
    23.             System.out.println("after get " + msg);  
    24.             out.write(msg + "<br>");  
    25.             if (m.isEmpty()) {  
    26.                 end = true;  
    27.             }  
    28.         }  
    29.         out.close();  
    30.     }  
    31.   
    32.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
    33.             throws ServletException, IOException {  
    34.         doGet(request, response);  
    35.     }  
    36.   
    37. }  

    下面是添加消息的servlet

    1. package hyjc.listener;  
    2.   
    3. import java.io.IOException;  
    4. import java.io.PrintWriter;  
    5.   
    6. import javax.servlet.ServletException;  
    7. import javax.servlet.http.HttpServlet;  
    8. import javax.servlet.http.HttpServletRequest;  
    9. import javax.servlet.http.HttpServletResponse;  
    10.   
    11. public class PutMsg extends HttpServlet {  
    12.   
    13.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
    14.             throws ServletException, IOException {  
    15.   
    16.         response.setContentType("text/html");  
    17.         System.out.println("put message");  
    18.         PrintWriter out = response.getWriter();  
    19.         out.flush();  
    20.         String msg = request.getParameter("message");  
    21.         if (null != msg) {  
    22.             MessageList.getInstance().add(msg);  
    23.         } else {  
    24.             System.out.println("添加消息:" + msg + "成果");  
    25.         }  
    26.         out.close();  
    27.     }  
    28.   
    29.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
    30.             throws ServletException, IOException {  
    31.         doGet(request, response);  
    32.     }  
    33.   
    34. }  

    下面是存放消息的消息队列,内部用阻塞队列使用

    1. package hyjc.listener;  
    2.   
    3. import java.util.Iterator;  
    4. import java.util.concurrent.LinkedBlockingQueue;  
    5.   
    6. public class MessageList {  
    7.   
    8.     private static MessageList list = null;  
    9.   
    10.     private static Object key = new Object();  
    11.   
    12.     private MessageList() {  
    13.         this.add("hello");  
    14.         this.add("world");  
    15.     }  
    16.   
    17.     public static MessageList getInstance() {  
    18.         synchronized (key) {  
    19.             if (list == null) {  
    20.                 list = new MessageList();  
    21.             }  
    22.             return list;  
    23.         }  
    24.     }  
    25.   
    26.     private LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>();  
    27.   
    28.     public boolean isEmpty() {  
    29.         return queue.isEmpty();  
    30.     }  
    31.   
    32.     public int size() {  
    33.         return queue.size();  
    34.     }  
    35.   
    36.     public String get() {  
    37.         try {  
    38.             return queue.take();  
    39.         } catch (InterruptedException e) {  
    40.             e.printStackTrace();  
    41.             return null;  
    42.         }  
    43.     }  
    44.   
    45.     public void clear() {  
    46.         queue.clear();  
    47.     }  
    48.   
    49.     public void add(String msg) {  
    50.         try {  
    51.             queue.put(msg);  
    52.         } catch (InterruptedException e) {  
    53.             e.printStackTrace();  
    54.         }  
    55.     }  
    56.   
    57.     public Iterator<String> iterator() {  
    58.         return queue.iterator();  
    59.     }  
    60. }  

    下面是演示效果,输入message,点击submit,就会添加到MessageList中,然后会在GetMsg中继续执行,实现长连接

    其它相关文章

    http://yiminghe.javaeye.com/blog/284953

    http://yiminghe.javaeye.com/blog/294781 

    http://yiminghe.javaeye.com/blog/300050 

  • 相关阅读:
    Extjs4.0中清空filefield已选文件
    .net操作读取word中的图像并保存
    WebForm_PostBackOptions未定义 错误排查
    数据库关键字
    VS2008生成WebSite和WebApplication的区别(转载)
    安装天乙论坛(SSH架构的开源项目)时遇到的问题
    Hibernate与Oracle char类型的列之间的兼容问题
    关于spring3使用AOP编程时需要引入哪些jar包的问题
    让IE支持HTML5的Canvas
    IIS + TOMCAT 注意事项
  • 原文地址:https://www.cnblogs.com/likwo/p/1895362.html
Copyright © 2020-2023  润新知