基於AJAX的長輪詢(long-polling)方式實現簡單的聊天室程序


原理:

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

AJAX 的出現使得 JavaScript 可以調用 XMLHttpRequest 對象發出 HTTP 請求,JavaScript 響應處理函數根據服務器返回的信息對 HTML 頁面的顯示進行更新。使用 AJAX 實現“服務器推”與傳統的 AJAX 應用不同之處在於:

  1. 服務器端會阻塞請求直到有數據傳遞或超時才返回。
  2. 客戶端 JavaScript 響應處理函數會在處理完服務器返回的信息后,再次發出請求,重新建立連接。
  3. 當客戶端處理接收的數據、重新建立連接時,服務器端可能有新的數據到達;這些信息會被服務器端保存直到客戶端重新建立連接,客戶端會一次把當前服務器端所有的信息取回。

聊天頁面的代碼:

   基於AJAX的長輪詢(long-polling)方式實現簡單的聊天室程序

 

定義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.getElementByIdx_x_x("message").value}});  
  14. }  
  15.   

 

 下面是獲得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 + "
    ");  
  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 queue = new LinkedBlockingQueue();  
  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 iterator() {  
  58.         return queue.iterator();  
  59.     }  
  60. }  

下面是演示效果,輸入message,點擊submit,就會添加到MessageList中,然后會在GetMsg中繼續執行,實現長連接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM