这是一个用自己实现的HTTP长连接做的聊天室.
HTTP长连接。在index.html,发起一个异步请求。在请求的Servlet里,把当前sessionId和线程加入到映射列表中,然后把当前线程wait()。在其他人登陆或者发消息的时候,让映射里的所有线程notify(),notify()之后会返回一些数据到页面,页面接收处理之后,再次发起一个新的请求。
1.Constants.java,存储会话,消息,会话线程映射集合.
2.SessionListener.java,监听Session的创建和销毁,维护会话列表.
3.Initialization.java,获取用户列表和消息列表
4.RefreshUserList.java,长连接刷新信息.
5.SendMessage,发送消息.
6.Util,工具类.
7.页面
HTTP长连接。在index.html,发起一个异步请求。在请求的Servlet里,把当前sessionId和线程加入到映射列表中,然后把当前线程wait()。在其他人登陆或者发消息的时候,让映射里的所有线程notify(),notify()之后会返回一些数据到页面,页面接收处理之后,再次发起一个新的请求。
1.Constants.java,存储会话,消息,会话线程映射集合.
- package com.rx.chart.common;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- /**
- * 公共属性
- *
- * @author Renxin
- *
- */
- public class Constants {
- /**
- * Session集合
- */
- public static List<String> users = new ArrayList<String>();
- /**
- * 消息集合
- */
- public static List<String> messages = new ArrayList<String>();
- /**
- * 会话线程映射
- * Key:SessionId
- * Value:Thread
- */
- public static Map<String, Thread> sessionThreadMapping = new HashMap<String, Thread>();
- }
2.SessionListener.java,监听Session的创建和销毁,维护会话列表.
- package com.rx.chart.listener;
- import static com.rx.chart.common.Constants.users;
- import javax.servlet.http.HttpSessionEvent;
- import javax.servlet.http.HttpSessionListener;
- import com.rx.chart.util.Util;
- /**
- * Session监听器
- *
- * @author Renxin
- *
- */
- public class SessionListener implements HttpSessionListener {
- public void sessionCreated(HttpSessionEvent httpsessionevent) {
- // 加入到Session集合
- users.add(httpsessionevent.getSession().getId());
- // 唤醒全部更新列表
- Util.wakeUpAllThread();
- }
- public void sessionDestroyed(HttpSessionEvent httpsessionevent) {
- // 从Session集合移除
- users.remove(httpsessionevent.getSession().getId());
- // 唤醒全部更新列表
- Util.wakeUpAllThread();
- }
- }
3.Initialization.java,获取用户列表和消息列表
- package com.rx.chart.servlet;
- import java.io.IOException;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import com.rx.chart.util.Util;
- /**
- * 初始化
- *
- * @author Renxin
- *
- */
- public class Initialization extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- // 返回消息
- Util.out(response);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doGet(request, response);
- }
- }
4.RefreshUserList.java,长连接刷新信息.
- package com.rx.chart.servlet;
- import java.io.IOException;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import com.rx.chart.common.Constants;
- import com.rx.chart.util.Util;
- /**
- * 刷新
- *
- * @author Renxin
- *
- */
- public class RefreshUserList extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- HttpSession session = request.getSession();
- // 加入映射
- Constants.sessionThreadMapping.put(session.getId(), Thread
- .currentThread());
- // 当前线程等待
- try {
- synchronized (Thread.currentThread()) {
- Thread.currentThread().wait();
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- // 返回消息
- Util.out(response);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doGet(request, response);
- }
- }
5.SendMessage,发送消息.
- package com.rx.chart.servlet;
- import java.io.IOException;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import com.rx.chart.common.Constants;
- import com.rx.chart.util.Util;
- /**
- * 发送消息
- *
- * @author Renxin
- *
- */
- public class SendMessage extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- HttpSession session = request.getSession();
- String message = request.getParameter("message");
- message = session.getId() + ":" + message;
- Constants.messages.add(message);
- // 唤醒全部更新列表
- Util.wakeUpAllThread();
- // 返回消息
- Util.out(response);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doGet(request, response);
- }
- }
6.Util,工具类.
- package com.rx.chart.util;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import javax.servlet.http.HttpServletResponse;
- import com.rx.chart.common.Constants;
- import flexjson.JSONSerializer;
- /**
- * 工具类
- *
- * @author Renxin
- *
- */
- public class Util {
- /**
- * 唤醒全部
- */
- public static void wakeUpAllThread() {
- Iterator<Map.Entry<String, Thread>> iterator = Constants.sessionThreadMapping
- .entrySet().iterator();
- while (iterator.hasNext()) {
- Map.Entry<String, Thread> entry = iterator.next();
- Thread thread = entry.getValue();
- synchronized (thread) {
- thread.notify();
- }
- }
- }
- /**
- * 唤醒指定
- *
- * @param sessionId
- */
- public static void wakeUpAllThread(String sessionId) {
- Iterator<Map.Entry<String, Thread>> iterator = Constants.sessionThreadMapping
- .entrySet().iterator();
- while (iterator.hasNext()) {
- Map.Entry<String, Thread> entry = iterator.next();
- if (sessionId.equals(entry.getKey())) {
- Thread thread = entry.getValue();
- synchronized (thread) {
- thread.notify();
- }
- }
- }
- }
- /**
- * 输出用户列表
- *
- * @param response
- * @throws IOException
- */
- public static void out(HttpServletResponse response) throws IOException {
- Map<String, List<String>> map = new HashMap<String, List<String>>();
- map.put("users", Constants.users);
- map.put("messages", Constants.messages);
- response.setContentType("text/html");
- PrintWriter out = response.getWriter();
- out.print(new JSONSerializer().serialize(map));
- out.flush();
- out.close();
- }
- }
7.页面
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <%
- String path = request.getContextPath();
- String basePath = request.getScheme() + "://"
- + request.getServerName() + ":" + request.getServerPort()
- + path + "/";
- %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <base href="<%=basePath%>">
- <title>首页</title>
- <script type="text/javascript" src="js/jquery-1.7.1.min.js">
- </script>
- </head>
- <body>
- <div>
- <div>
- <h2>
- 用户列表
- </h2>
- </div>
- <div id="userList"></div>
- </div>
- <div>
- <div>
- <h2>
- 消息列表
- </h2>
- </div>
- <div id="messageList"></div>
- </div>
- <div>
- <input type="text" id="message" />
- <input type="button" value="发送" οnclick="subMsg();" />
- </div>
- </body>
- </html>
- <script type="text/javascript">
- //处理内容
- function handlerContent(content) {
- eval('var c=' + content);
- if (c.users) {
- var html;
- html = '<ul>';
- for ( var u in c.users) {
- html += '<li>';
- html += c.users[u];
- html += '</li>';
- }
- html += '</ul>';
- $('#userList').html(html);
- }
- if (c.messages) {
- var html;
- html = '<ul>';
- for ( var m in c.messages) {
- html += '<li>';
- html += c.messages[m];
- html += '</li>';
- }
- html += '</ul>';
- $('#messageList').html(html);
- }
- }
- //发消息
- function subMsg() {
- $.post('SendMessage', {
- 'message' : $('#message').val()
- }, function(content) {
- handlerContent(content);
- });
- $('#message').val('');
- }
- //初始化
- function init() {
- $.post('Initialization', function(content) {
- handlerContent(content);
- refreshUserList();
- });
- }
- //刷新列表
- function refreshUserList() {
- $.post('RefreshUserList', function(content) {
- handlerContent(content);
- refreshUserList();
- });
- }
- window.onload = init();
- </script>