`
小鑫。
  • 浏览: 134801 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

 
阅读更多
这是一个用自己实现的HTTP长连接做的聊天室.
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="发送" onclick="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>
分享到:
评论
7 楼 小鑫。 2014-11-14  
KevinDai007 写道
小鑫。 写道
KevinDai007 写道
这个项目的用户列表是怎么会事?为什么我完全看不懂

哪个地方不懂?

我登录之后挂在哪里面,一会用户列表就变了,也就是sessionid变了,这是为什么

以前那个超时了?
6 楼 KevinDai007 2014-11-13  
小鑫。 写道
KevinDai007 写道
这个项目的用户列表是怎么会事?为什么我完全看不懂

哪个地方不懂?

我登录之后挂在哪里面,一会用户列表就变了,也就是sessionid变了,这是为什么
5 楼 小鑫。 2014-11-12  
KevinDai007 写道
这个项目的用户列表是怎么会事?为什么我完全看不懂

哪个地方不懂?
4 楼 KevinDai007 2014-11-12  
这个项目的用户列表是怎么会事?为什么我完全看不懂
3 楼 小鑫。 2012-11-27  
k11hao 写道
发送消息的速度特别快,那个pushlet用起来总是怪怪的

k11hao 写道
发送消息的速度特别快,那个pushlet用起来总是怪怪的


谢谢欣赏.
这个是写来玩的,pushlet那么多人用,可定有它的特别之处,我想应该是没调好吧,
2 楼 k11hao 2012-11-25  
发送消息的速度特别快,那个pushlet用起来总是怪怪的
1 楼 k11hao 2012-11-25  
我觉得这样写很不错

相关推荐

    asp.net 长连接(聊天室例子)

    ASP.NET长连接是一种在Web应用中实现实时通信的技术,尤其适用于构建聊天室、实时通知等需要持续更新数据的应用场景。传统的HTTP协议是基于短连接的,每次请求和响应之间都会断开连接,这在实时性要求高的应用中效率...

    基于长连接的简易聊天室jQuery+.net 2.0 Comet

    基于长连接的简易聊天室jQuery+.net 2.0 Comet Comet练手,尚有不少bug,还未实现维护用户列表功能 是长连接的不是轮询方式 升级版本 http://download.csdn.net/source/2216847

    基于linux的TCP网络聊天室设计与实现

    5. **并发处理**:在客户端,多进程可以同时处理多个用户的活动,而在服务器端,多线程可以同时处理来自多个客户端的连接请求,实现了并发处理,保证了聊天室的实时性。 6. **数据传输格式**:在网络通信中,通常...

    eclipse实现的聊天室

    本项目"eclipse实现的聊天室"提供了一个实用的示例,旨在帮助开发者了解如何利用Eclipse来构建实时通信的应用。这个聊天室示例不仅能够加深对网络编程的理解,还能展示多线程、套接字编程以及并发处理等关键概念。 ...

    聊天室的实现

    本文将深入探讨如何使用VC++2008来实现一个简单的聊天室,涉及的知识点主要包括网络编程的基本原理、套接字(Socket)编程、多线程以及客户端与服务器之间的通信机制。 首先,我们需要理解网络编程的基础概念。网络...

    linux系统下实现聊天室

    要创建一个聊天室服务器,我们需要使用`socket()`函数创建一个套接字,然后用`bind()`函数绑定一个本地IP地址和端口号,再用`listen()`函数设置最大连接队列长度,例如5个,表示服务器最多可以同时处理5个客户端的...

    聊天室连接数据库的设计

    本文将深入探讨聊天室连接数据库的设计,旨在提供一个简单明了、易学易用的方案,帮助您更好地理解和实现此类系统。 首先,我们需要确定数据库的基本架构。在聊天室系统中,通常会涉及到以下几种主要的数据表: 1....

    VC实现聊天室服务端及客户端程序

    《VC实现聊天室服务端及客户端程序》 在IT领域,开发一款聊天室程序是学习网络编程和客户端-服务器架构的常见实践。本项目利用Microsoft Foundation Classes (MFC)库,一个C++类库,来构建一个具备基本聊天功能的...

    linux 下的shell socket实现聊天室

    在实现聊天室的过程中,管道可能用于在客户端将用户输入传递给`nc`命令,或者在服务器端将接收到的消息广播给所有连接的客户端。 在提供的压缩包文件中,`client.tar.gz`和`server.tar.gz`分别包含了客户端和服务器...

    聊天室功能实现

    下面将详细阐述实现这样一个聊天室功能所涉及的关键知识点。 首先,我们要实现“注册”功能。这通常包括用户创建账号、设置密码、验证邮箱或手机号等步骤。在后端,我们需要设计一个用户数据库来存储用户名、密码...

    asp.net 长连接的聊天室(多人房间)

    ASP.NET长连接的聊天室是一种实现高实时性的在线交流平台,尤其适合于多人参与的讨论环境。这种聊天室的核心技术是Comet,一种用于创建服务器推送(Server-Sent Events)的编程模型,允许服务器主动向客户端发送数据...

    C#多线程与Socket聊天室的实现

    本文将深入探讨如何使用C#语言实现一个基于TCP/IP协议的多线程Socket聊天室。这个聊天室功能允许局域网内的多台计算机进行实时信息交互,虽然没有在广域网环境下测试,但在局域网内能有效工作。 首先,我们要理解...

    asp.net 长连接(聊天室例子)打包成解决方案

    ASP.NET长连接是一种在Web应用中实现实时通信的技术,尤其适用于构建聊天室或推送通知等需要持续更新信息的场景。在这个"asp.net 长连接(聊天室例子)打包成解决方案"中,开发者提供了一个具体的实例来演示如何在...

    tomcat实现websocket聊天室

    在这个“tomcat实现websocket聊天室”的项目中,我们将深入探讨如何利用Tomcat搭建一个具备单聊、群聊、数据库管理以及用户管理功能的聊天室。 首先,我们需要理解WebSocket API的基本概念。WebSocket协议定义了两...

    利用Qt使用TCP通信实现多人在线聊天室

    在我们的多人聊天室项目中,服务器端需要监听客户端的连接,并处理来自多个客户端的数据。当一个新客户端连接时,服务器会创建一个新的`QTcpSocket`实例来管理这个连接。客户端使用`QTcpSocket`连接到服务器并发送...

    多人聊天室的实现思路分析

    多人聊天室的实现是网络编程中的一...以上是对多人聊天室实现思路的详细分析,实际开发中还需要结合具体的编程语言、框架和工具进行实践。对于学习和参考,可以查看给定的博文链接,那里可能有更具体的实现细节和案例。

    java实现聊天室功能(全部代码,有界面)

    Java 实现聊天室功能 Java 实现聊天室功能是通过使用 Java 语言和 Swing 库来创建一个多人聊天室系统。该系统支持群聊、公聊、私聊等功能,並支持刷新好友列表。 title: Java 实现聊天室功能(全部代码,有界面) ...

    多人聊天室python实现

    【标题】"多人聊天室python实现"涉及到的核心技术是使用Python编程语言构建一个支持多用户交互的聊天系统。在Python中,这样的应用通常基于网络通信协议TCP(Transmission Control Protocol)来建立连接,允许多个...

    简单Ajax聊天室 实现聊天功能

    本项目“简单Ajax聊天室 实现聊天功能”利用ASP.NET框架和Ajax技术,构建了一个实时、交互性强的在线聊天平台。在这个聊天室中,用户不仅能发送文字消息,还能调整字体样式、颜色,并发送QQ表情,极大地提升了用户...

Global site tag (gtag.js) - Google Analytics