聊天室(自己实现HTTP长连接)

这是一个用自己实现的HTTP长连接做的聊天室.
HTTP长连接。在index.html,发起一个异步请求。在请求的Servlet里,把当前sessionId和线程加入到映射列表中,然后把当前线程wait()。在其他人登陆或者发消息的时候,让映射里的所有线程notify(),notify()之后会返回一些数据到页面,页面接收处理之后,再次发起一个新的请求。

1.Constants.java,存储会话,消息,会话线程映射集合.
Java代码   收藏代码
  1. package com.rx.chart.common;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. /** 
  9.  * 公共属性 
  10.  *  
  11.  * @author Renxin 
  12.  *  
  13.  */  
  14. public class Constants {  
  15.   
  16.     /** 
  17.      * Session集合 
  18.      */  
  19.     public static List<String> users = new ArrayList<String>();  
  20.   
  21.     /** 
  22.      * 消息集合 
  23.      */  
  24.     public static List<String> messages = new ArrayList<String>();  
  25.   
  26.     /** 
  27.      * 会话线程映射  
  28.      * Key:SessionId  
  29.      * Value:Thread 
  30.      */  
  31.     public static Map<String, Thread> sessionThreadMapping = new HashMap<String, Thread>();  
  32.   
  33. }  


2.SessionListener.java,监听Session的创建和销毁,维护会话列表.
Java代码   收藏代码
  1. package com.rx.chart.listener;  
  2.   
  3. import static com.rx.chart.common.Constants.users;  
  4.   
  5. import javax.servlet.http.HttpSessionEvent;  
  6. import javax.servlet.http.HttpSessionListener;  
  7.   
  8. import com.rx.chart.util.Util;  
  9.   
  10. /** 
  11.  * Session监听器 
  12.  *  
  13.  * @author Renxin 
  14.  *  
  15.  */  
  16. public class SessionListener implements HttpSessionListener {  
  17.   
  18.     public void sessionCreated(HttpSessionEvent httpsessionevent) {  
  19.   
  20.         // 加入到Session集合  
  21.         users.add(httpsessionevent.getSession().getId());  
  22.   
  23.         // 唤醒全部更新列表  
  24.         Util.wakeUpAllThread();  
  25.   
  26.     }  
  27.   
  28.     public void sessionDestroyed(HttpSessionEvent httpsessionevent) {  
  29.   
  30.         // 从Session集合移除  
  31.         users.remove(httpsessionevent.getSession().getId());  
  32.   
  33.         // 唤醒全部更新列表  
  34.         Util.wakeUpAllThread();  
  35.   
  36.     }  
  37.   
  38. }  


3.Initialization.java,获取用户列表和消息列表
Java代码   收藏代码
  1. package com.rx.chart.servlet;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9.   
  10. import com.rx.chart.util.Util;  
  11.   
  12. /** 
  13.  * 初始化 
  14.  *  
  15.  * @author Renxin 
  16.  *  
  17.  */  
  18. public class Initialization extends HttpServlet {  
  19.   
  20.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  21.             throws ServletException, IOException {  
  22.   
  23.         // 返回消息  
  24.         Util.out(response);  
  25.   
  26.     }  
  27.   
  28.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  29.             throws ServletException, IOException {  
  30.         doGet(request, response);  
  31.     }  
  32.   
  33. }  


4.RefreshUserList.java,长连接刷新信息.
Java代码   收藏代码
  1. package com.rx.chart.servlet;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9. import javax.servlet.http.HttpSession;  
  10.   
  11. import com.rx.chart.common.Constants;  
  12. import com.rx.chart.util.Util;  
  13.   
  14. /** 
  15.  * 刷新 
  16.  *  
  17.  * @author Renxin 
  18.  *  
  19.  */  
  20. public class RefreshUserList extends HttpServlet {  
  21.   
  22.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  23.             throws ServletException, IOException {  
  24.   
  25.         HttpSession session = request.getSession();  
  26.   
  27.         // 加入映射  
  28.         Constants.sessionThreadMapping.put(session.getId(), Thread  
  29.                 .currentThread());  
  30.   
  31.         // 当前线程等待  
  32.         try {  
  33.             synchronized (Thread.currentThread()) {  
  34.                 Thread.currentThread().wait();  
  35.             }  
  36.         } catch (InterruptedException e) {  
  37.             e.printStackTrace();  
  38.         }  
  39.   
  40.         // 返回消息  
  41.         Util.out(response);  
  42.   
  43.     }  
  44.   
  45.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  46.             throws ServletException, IOException {  
  47.         doGet(request, response);  
  48.     }  
  49.   
  50. }  


5.SendMessage,发送消息.
Java代码   收藏代码
  1. package com.rx.chart.servlet;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9. import javax.servlet.http.HttpSession;  
  10.   
  11. import com.rx.chart.common.Constants;  
  12. import com.rx.chart.util.Util;  
  13.   
  14. /** 
  15.  * 发送消息 
  16.  *  
  17.  * @author Renxin 
  18.  *  
  19.  */  
  20. public class SendMessage extends HttpServlet {  
  21.   
  22.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  23.             throws ServletException, IOException {  
  24.   
  25.         HttpSession session = request.getSession();  
  26.   
  27.         String message = request.getParameter("message");  
  28.         message = session.getId() + ":" + message;  
  29.   
  30.         Constants.messages.add(message);  
  31.   
  32.         // 唤醒全部更新列表  
  33.         Util.wakeUpAllThread();  
  34.   
  35.         // 返回消息  
  36.         Util.out(response);  
  37.     }  
  38.   
  39.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  40.             throws ServletException, IOException {  
  41.         doGet(request, response);  
  42.     }  
  43.   
  44. }  


6.Util,工具类.
Java代码   收藏代码
  1. package com.rx.chart.util;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.HashMap;  
  6. import java.util.Iterator;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9.   
  10. import javax.servlet.http.HttpServletResponse;  
  11.   
  12. import com.rx.chart.common.Constants;  
  13.   
  14. import flexjson.JSONSerializer;  
  15.   
  16. /** 
  17.  * 工具类 
  18.  *  
  19.  * @author Renxin 
  20.  *  
  21.  */  
  22. public class Util {  
  23.   
  24.     /** 
  25.      * 唤醒全部 
  26.      */  
  27.     public static void wakeUpAllThread() {  
  28.         Iterator<Map.Entry<String, Thread>> iterator = Constants.sessionThreadMapping  
  29.                 .entrySet().iterator();  
  30.         while (iterator.hasNext()) {  
  31.             Map.Entry<String, Thread> entry = iterator.next();  
  32.             Thread thread = entry.getValue();  
  33.             synchronized (thread) {  
  34.                 thread.notify();  
  35.             }  
  36.         }  
  37.     }  
  38.   
  39.     /** 
  40.      * 唤醒指定 
  41.      *  
  42.      * @param sessionId 
  43.      */  
  44.     public static void wakeUpAllThread(String sessionId) {  
  45.         Iterator<Map.Entry<String, Thread>> iterator = Constants.sessionThreadMapping  
  46.                 .entrySet().iterator();  
  47.         while (iterator.hasNext()) {  
  48.             Map.Entry<String, Thread> entry = iterator.next();  
  49.             if (sessionId.equals(entry.getKey())) {  
  50.                 Thread thread = entry.getValue();  
  51.                 synchronized (thread) {  
  52.                     thread.notify();  
  53.                 }  
  54.             }  
  55.         }  
  56.     }  
  57.   
  58.     /** 
  59.      * 输出用户列表 
  60.      *  
  61.      * @param response 
  62.      * @throws IOException 
  63.      */  
  64.     public static void out(HttpServletResponse response) throws IOException {  
  65.         Map<String, List<String>> map = new HashMap<String, List<String>>();  
  66.         map.put("users", Constants.users);  
  67.         map.put("messages", Constants.messages);  
  68.   
  69.         response.setContentType("text/html");  
  70.         PrintWriter out = response.getWriter();  
  71.         out.print(new JSONSerializer().serialize(map));  
  72.         out.flush();  
  73.         out.close();  
  74.     }  
  75.   
  76. }  


7.页面
Java代码   收藏代码
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3.     String path = request.getContextPath();  
  4.     String basePath = request.getScheme() + "://"  
  5.             + request.getServerName() + ":" + request.getServerPort()  
  6.             + path + "/";  
  7. %>  
  8.   
  9. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  10. <html>  
  11.     <head>  
  12.         <base href="<%=basePath%>">  
  13.   
  14.         <title>首页</title>  
  15.         <script type="text/javascript" src="js/jquery-1.7.1.min.js">  
  16. </script>  
  17.     </head>  
  18.   
  19.     <body>  
  20.         <div>  
  21.             <div>  
  22.                 <h2>  
  23.                     用户列表  
  24.                 </h2>  
  25.             </div>  
  26.             <div id="userList"></div>  
  27.         </div>  
  28.   
  29.         <div>  
  30.             <div>  
  31.                 <h2>  
  32.                     消息列表  
  33.                 </h2>  
  34.             </div>  
  35.             <div id="messageList"></div>  
  36.         </div>  
  37.   
  38.         <div>  
  39.             <input type="text" id="message" />  
  40.             <input type="button" value="发送" οnclick="subMsg();" />  
  41.         </div>  
  42.     </body>  
  43. </html>  
  44. <script type="text/javascript">  
  45. //处理内容  
  46. function handlerContent(content) {  
  47.     eval('var c=' + content);  
  48.     if (c.users) {  
  49.         var html;  
  50.         html = '<ul>';  
  51.         for ( var u in c.users) {  
  52.             html += '<li>';  
  53.             html += c.users[u];  
  54.             html += '</li>';  
  55.         }  
  56.         html += '</ul>';  
  57.         $('#userList').html(html);  
  58.     }  
  59.   
  60.     if (c.messages) {  
  61.         var html;  
  62.         html = '<ul>';  
  63.         for ( var m in c.messages) {  
  64.             html += '<li>';  
  65.             html += c.messages[m];  
  66.             html += '</li>';  
  67.         }  
  68.         html += '</ul>';  
  69.         $('#messageList').html(html);  
  70.     }  
  71. }  
  72.   
  73. //发消息  
  74. function subMsg() {  
  75.     $.post('SendMessage', {  
  76.         'message' : $('#message').val()  
  77.     }, function(content) {  
  78.         handlerContent(content);  
  79.     });  
  80.     $('#message').val('');  
  81. }  
  82.   
  83. //初始化  
  84. function init() {  
  85.     $.post('Initialization', function(content) {  
  86.         handlerContent(content);  
  87.         refreshUserList();  
  88.     });  
  89. }  
  90.   
  91. //刷新列表  
  92. function refreshUserList() {  
  93.     $.post('RefreshUserList', function(content) {  
  94.         handlerContent(content);  
  95.         refreshUserList();  
  96.     });  
  97. }  
  98.   
  99. window.onload = init();  
  100. </script> 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值