ajax聊天室
ChatRoom主要定义一个聊天室类,封装了聊天信息和聊天室核心类,这是在服务端编译的执行的,且只能有一个chatroom对象,所以用singleton模式
1
using System;2
using System.Web;3
using System.Collections.Generic;4
using System.Collections;5
using System.Web.Security;6
namespace ajax_xmlhttp7


{8
9
public class chatMessage10

{11
private LinkedList<string> msgque = new LinkedList<string>();12
private readonly int max = 15;13
public void addMessage(string msg)14

{15
string s = msg + "<br/>";16
if (msgque.Count >= max)17
msgque.RemoveLast();18
msgque.AddFirst(s);19
20
}21

22
public string getMessage(string username)23

{24
string res = "";25
if (msgque.Count > 0)26

{27
IEnumerator em = msgque.GetEnumerator();28
bool first = true;29
while (em.MoveNext())30

{31
string s = (string)em.Current;32
if (s.Contains("[$private$]"))//为私有消息33

{34
string to=s.Substring(11,s.IndexOf(@"[$private$/]",0,StringComparison.OrdinalIgnoreCase)-11);35
string msg=s.Substring(s.IndexOf(@"[$private$/]",0,StringComparison.OrdinalIgnoreCase)+12);36
if (username == to)37

{38
if (first)39

{40
res += "<font color=\"#FF0000\">" + msg + "</font>";41
first = false;42
}43
else44
res += msg;45
}46
}47
48
else if (first)49

{50
res+= "<font color=\"#FF0000\">" + s + "</font>";51
first = false;52
}53
else res += s;54
55
}56
}57
return res;58
}59
60

61
}62

63
64
65
66
67

68
public class ChatRoom69

{70
private Hashtable Users = new Hashtable();71
private Hashtable update = new Hashtable();72
private chatMessage ChatContainer = new chatMessage();73
private object block = new object();74
private static ChatRoom _instance=new ChatRoom ();75
static public ChatRoom Instance76

{77

get
{ return _instance; }78

79
}80
public bool userLogined(string username)81

{82
return Users.ContainsKey(username) ? !isExpired(username) : false;83
}84
public string addUser(string username)85

{86
if(username.Trim()=="")87
return "Err:username null";88
if(Users.Contains(username))89
return "Err:username exists";90
lock (block)91

{92
Users.Add(username, username);93
update.Add(username, DateTime.Now);94
}95
ChatContainer.addMessage("系统消息: 欢迎" + username + "进入聊天室!");96
return "Suc:add successed";97

98
}99

100
public string removeUser(string username)101

{102
103
if(username.Trim() != "" && Users.Contains(username) )104

{105
106
lock (block)107

{108
Users.Remove(username);109
update.Remove(username);110
FormsAuthentication.SignOut();111
}112
ChatContainer.addMessage("系统消息: " + username + "已经退出聊天室!");113
return "suc:remove successed";114
115
116
}117
return "Err:user invalid";118
}119

120
public string getUserList(string username)121

{122
string ulist = "";123
IEnumerator em = Users.Keys.GetEnumerator();124
while(em.MoveNext())125

{126

127
ulist += "<li><a href=\"#\" onclick=\"javascript:document.getElementById('who').value='" + (string)em.Current + "';\">" + (string)em.Current + "</a></li>";128
}129
return ulist;130
}131
public string chat(string username,string msg,bool Private,string to)132

{133
ChatContainer.addMessage((Private?"[$private$]"+to+"[$private$/]":"")+username + ": " + msg);134
return "suc:";135
}136
public string getMessage(string username)137

{138
139
return ChatContainer.getMessage(username);140
}141
public string updateUser(string username)142

{143
DateTime lastupdate = new DateTime();144
lastupdate = DateTime.Now;145
if (isExpired(username))146

{147
return @"[&signout&]";148

149
}150
update[username] = lastupdate;151
return lastupdate.ToString();152

153
154
}155

156
public bool isExpired(string username)157

{158
string s="suc:remove successed";159
return DateTime.Now - (DateTime)update[username] > new TimeSpan(0, 30, 0)?removeUser(username)==s:false;160
}161

162
}163

164
165

166
}服务端chatroom设计好后,就要设计一个HttpHandler来处理客户端的异步请求,Handler类必须实现IHttpHandler接口和IsReusable属性,代码为
1
<%@ WebHandler Language="C#" Class="Handler" %>2
using System;3
using System.Web;4
using System.Web.Security;5
using System.Text;6
using ajax_xmlhttp;7
public class Handler : IHttpHandler8


{9
public void ProcessRequest(HttpContext context)10

{11
context.Response.ContentType = "text/plain";12
string action = context.Request.QueryString["action"];13
string username = null;14
username = context.User.Identity.Name;15
if (username == null || !ChatRoom.Instance.userLogined(username))16

{17

18

19
context.Response.Write("##signout##");20
context.Response.Flush();21
context.Response.Close();22
return;23
}24

25

26

27
switch (action)28

{29

30
case "chat": HttpContext.Current.Response.Write(ChatRoom.Instance.chat(username, context.Request.QueryString["msg"],false,"")); break;31
case "loginout": HttpContext.Current.Response.Write(ChatRoom.Instance.removeUser(username)); break;32
case "get": HttpContext.Current.Response.Write(ChatRoom.Instance.getMessage(username)); break;33
case "update": HttpContext.Current.Response.Write(ChatRoom.Instance.updateUser(username)); break;34
case "list": HttpContext.Current.Response.Write(ChatRoom.Instance.getUserList(username)); break;35
case "private": HttpContext.Current.Response.Write(ChatRoom.Instance.chat(username, context.Request.QueryString["msg"], true, context.Request.QueryString["to"])); break;36
}37
38
HttpContext.Current.Response.Flush();39
HttpContext.Current.Response.Close();40
}41

42
public bool IsReusable43

{44

get
{ return false; }45
}46
}47

接下来就是客户端的实现了,简单的登陆页面
1
using System;2
using System.Collections.Generic;3
using System.Linq;4
using System.Web;5
using System.Web.UI;6
using System.Web.UI.WebControls;7
using System.Web.Security;8
namespace ajax_xmlhttp9


{10
public partial class login : System.Web.UI.Page11

{12
protected void Page_Load(object sender, EventArgs e)13

{14

15
}16

17
protected void Button1_Click(object sender, EventArgs e)18

{19
string id=TextBox1.Text.Trim();20
21
if (id == "")22

{23
Label2.Text = "请输入正确ID";24
return;25
}26
else if (ChatRoom.Instance.userLogined(id))27

{28
Label2.Text = "用户已经存在";29
return;30
}31
else32

{33
ChatRoom.Instance.addUser(id);34
FormsAuthentication.RedirectFromLoginPage(id,true);35
36
37
38
}39
40
41
}42
}43
}44

接下来是Default.aspx页面的设计和客户端异步请求数据逻辑实现
1

<%
@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ajax_xmlhttp._Default" %>2

3
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">4

5
<html xmlns="http://www.w3.org/1999/xhtml" >6
<head runat="server">7
<title></title>8

<style type="text/css">
9
.style110

{
}{11
width: 80%;12
}13
.style214

{
}{15
height: 64px;16
}17
#Text118

{
}{19
width: 87px;20
height: 17px;21
}22
.style323

{
}{24
width: 80px;25
}26
.style527

{
}{28
height: 62px;29
width: 472px;30
}31
.style632

{
}{33
width: 48px;34
}35
.style736

{
}{37
width: 67px;38
}39
</style>40

41

<script language="javascript" type="text/javascript">
42
// <!CDATA[43
var xmlhttp1;44
var xmlhttp2;45
var xmlhttp3;46
var xmlhttp4;47
var xmlhttp5;48
var latestmsg="";49

function send_onclick()
{50
var msgtosend = document.getElementById('inputmsg').value;51

if (msgtosend== "")
{52
alert("信息不能为空啊!");53
return;54
}55
if (!Checkbox1.checked)56

if (who.value == "")
{57
alert("请先选择要私聊的对象");58
return;59
}60
xmlhttp1 =new ActiveXObject("Microsoft.XMLHTTP");61
xmlhttp1.onreadystatechange = _sendMessageCallBack;62
63
xmlhttp1.Open("POST", "Handler.ashx?action="+(Checkbox1.checked?"chat":"private&to="+who.value)+"&msg="+ escape(msgtosend),true);64
xmlhttp1.Send();65
66

67
}68

69

function _sendMessageCallBack()
{70
71
//判断异步调用是否已经完成72

if (xmlhttp1.readystate == 4)
{73
//判断完成的提示代码是否是OK状态74

if (xmlhttp1.status == 200)
{75
//将返回数据作为参数,传递给填充方法76
rep = xmlhttp1.responseText;77
document.getElementById("inputmsg").value = "";78
isOut(rep);79
80
81
82
}83
}84

85
}86
87

function getMessage()
{88
xmlhttp2 = new ActiveXObject("Microsoft.XMLHTTP");89
xmlhttp2.onreadystatechange = _getMessageCallBack;90
xmlhttp2.Open("POST", "Handler.ashx?action=get", true);91
xmlhttp2.Send();92

93
}94

function _getMessageCallBack()
{95

if (xmlhttp2.readystate == 4)
{96

if (xmlhttp2.status == 200)
{97
rep = xmlhttp2.responseText;98
isOut(rep);99
if (rep != latestmsg )100
document.all.sound.src = "S1.WAV";101
latestmsg = rep; 102
document.getElementById('chatcontent').innerHTML = rep;103
setTimeout(getMessage, 1000); 104
}105
}106
}107

108

function getUserList()
{109
xmlhttp3 = new ActiveXObject("Microsoft.XMLHTTP");110
xmlhttp3.onreadystatechange = _getUserListCallBack;111
xmlhttp3.Open("POST", "Handler.ashx?action=list", true);112
xmlhttp3.Send();113
}114

function _getUserListCallBack()
{115

if (xmlhttp3.readystate == 4)
{116

if (xmlhttp3.status == 200)
{117
rep = xmlhttp3.responseText;118
isOut(rep);119
document.getElementById('userlist').innerHTML = rep;120
setTimeout(getUserList, 5000);121
}122
}123
}124

function updateUser()
{125
xmlhttp4 = new ActiveXObject("Microsoft.XMLHTTP");126
xmlhttp4.onreadystatechange = _updateUserCallBack;127
xmlhttp4.Open("POST", "Handler.ashx?action=update", true);128
xmlhttp4.Send();129
}130

function _updateUserCallBack()
{131

if (xmlhttp4.readystate == 4)
{132

if (xmlhttp4.status == 200)
{133
rep = xmlhttp4.responseText;134
isOut(rep);135
setTimeout(updateUser, 2000);136
}137
}138
}139

140

function isOut(str)
{141

if (str == "##signout##")
{142
location.href = "login.aspx";143
144
}145

146
}147
var tt = 1;148

function Select1_onclick()
{149
tt = tt ? 0 : 1;150
if (tt)151
document.getElementById('inputmsg').value += "<img src=face/" + Select1.value + ">";152
}153
154

155
getMessage();156
getUserList();157
updateUser();158

159

function Button1_onclick()
{160
xmlhttp5 = new ActiveXObject("Microsoft.XMLHTTP");161
xmlhttp5.onreadystatechange = _loginOutCallBack;162
xmlhttp5.Open("POST", "Handler.ashx?action=loginout", true);163
xmlhttp5.Send();164
}165

function _loginOutCallBack()
{166

if (xmlhttp5.readystate == 4)
{167

if (xmlhttp5.status == 200)
{168
rep = xmlhttp5.responseText;169
isOut(rep);170
171
}172
}173
}174

175
// ]]>176
</script>177
</head>178
<body>179
<bgsound id="sound" src="" loop="1">180
<div style="height:100%;width:100%;" align="center">181
<div style="height: 500px; width: 600px;">182
183
<table style="width: 100%; height: 100%;" align="center">184
<tr style="height:10%;">185
<td align="center" colspan="2" class="style2" 186
style="background-color: #808000; border: medium solid #C0C0C0">187
Ajax聊天室</td>188
</tr>189
<tr style="height:70%;">190
<td class="style1">191
<div style="height: 100%;width:100%">192
<div id="chatcontent" style="border: thin solid #808000; height: 100%; width:100%; background-color: #C0C0C0;" 193
align="left">194
</div>195
</div>196
</td>197
<td>198
<div id="userlist" style="border: thin solid #C0C0C0; height: 100%; background-color: #C0C0C0;height:100%;width:100%;">199
</div>200
</td>201
</tr>202
<tr style="height:5%;" valign="middle">203
<td colspan="2" 204
>205
<div id="tools" 206
style="border: thin solid #C0C0C0; height: 100%; background-color: #C0C0C0;height:100%;width:100%;" 207
align="left">208
<span lang="zh-cn">表情</span><select id="Select1" class="style3" name="D1" onclick="return Select1_onclick()">209
<option value="smile.gif">微笑</option>210
<option value="angry.gif">生气</option>211
<option value="cry.gif">哭泣</option>212
</select><input id="Checkbox1" type="checkbox" value="checked" checked="checked" /><span 213
lang="zh-cn">公聊 214
私聊:<input id="who" class="style7" type="text" disabled="disabled" /></span></div>215
</td>216
</tr>217
<tr style="height:15%;">218
<td colspan="2" 219
>220
<div style="border: thin solid #008000; height:100%; background-color: #C0C0C0;height:100%;width:100%;" 221
align="left">222
<textarea id="inputmsg" class="style5"></textarea><input id="send" type="button" 223
value="发送" onclick="return send_onclick()" /><span lang="zh-cn"> 224
<input id="Button1" class="style6" type="button" value="退出" onclick="return Button1_onclick()" /></span></div>225
226
</td>227
</tr>228
</table>229
230
</div>231
</div>232
233
234
</body>235
</html>236

浙公网安备 33010602011771号