### 制作一个简单的社区聊天室

聊天室拉近了人与人之间的距离，是人与人之间交流的互动平台。自推出以来，一直倍受网民的青睐。本程序中，用户通过输入昵称就可以进入聊天室与其他网友进行互动。用户登录聊天室的界面如图 1 所示。

图 1 用户登录

输入昵称后，进入聊天页面。在页面的下方文本框中可以输入聊天信息，并可以选择“名称符号”、“名称颜色”、“字体颜色”，然后单击“发送(Alt+S)”按钮发送留言，这时在上方的显示区域就可以看到发布的信息。如图 2 所示。

图 2 输入信息并发送

说明：

运行本程序，必须将程序所在文件夹设置为网站的根目录。

在测试时，可以通过IIS管理器重新启动网站，来清除保存在Application对象中的数据。

#### 关键技术

本程序主要应用 Application 对象来保存用户昵称、聊天信息，使用了基于 Ajax 技术的开发环境，并在网页中嵌入了 iframe 浮动框架。

##### 1．Application 对象

Application 对象用于共享应用程序级信息。即多个用户共享一个 Application 对象。在应用程序关闭之前，Application 对象将一直存在。

例如，在 Global.asax 文件中初始化 Application 变量，代码如下：

void Application_Start(object sender, EventArgs e)

{

// 在应用程序启动时运行的代码

Application["count"] = 0;

Application["UserName"] = "所有人";

Application["Msg"] = "";

}

##### 2．Ajax 开发环境中的控件

l ScriptManager 控件

ScriptManager 控件用来处理页面上的所有 AJAX 组件以及页面局部更新，生成相关的客户端代理脚本以便能够在 JavaScript 中访问 Web Service，所有需要支持 ASP.NET AJAX 的 ASP.NET 页面上有且只能有一个 ScriptManager 控件。

说明：

设置 ScriptManager 控件的 EnablePartialRendering 属性为 True 时，表示仅对 UpdatePanel 控件区域范围内的部分刷新。如果设置为 False,对整个页面刷新。

l UpdatePanel 控件

UpdatePanel 控件主要用于规划和配置更新区域。也就是说，将需要更新的内容放置在该控件内。

l Timer 控件

Timer 控件是一个定时器控件。可以设定以特定时间规律触发。使用该控件可以设置更新的时间间隔，在该控件的 Tick 事件中编写自动触发的内容。

例如，在内容页 MsgContent.aspx 中添加 ScriptManager 控件、UpdatePanel 控件、Timer 控件，以刷新聊天内容。代码如下：

<div>

<asp:ScriptManager ID="ScriptManager1" runat="server">

</asp:ScriptManager>

</div>

<asp:UpdatePanel ID="UpdatePanel1" runat="server">

<ContentTemplate>

<table width="100%">

<tr>

<td colspan="3">

&nbsp;<asp:Label ID="lblMsg" runat="server" Text="加载聊天信息中........." BackColor="White" BorderColor="#400040" BorderWidth="1px" Width="99%" CssClass="bgg"></asp:Label><br />

&nbsp; &nbsp;&nbsp;

<asp:Label ID="lblcount" runat="server" Font-Bold="True" Font-Size="12px" ForeColor="Blue"

Text="正在统计在线人数......."></asp:Label>&nbsp;<strong> </strong>

</td>

</tr>

</table>

<asp:Timer ID="Timer1" runat="server" Interval="2000" OnTick="Timer1_Tick">

</asp:Timer>

</ContentTemplate>

</asp:UpdatePanel>

在后台页 MsgContent.aspx.cs 中编写 Timer1_Tick 事件，代码如下：

protected void Timer1_Tick(object sender, EventArgs e)

{

try

{

//获取聊天信息

lblMsg.Text = Application["Msg"].ToString();

//统计在线人数

lblcount.Text = "聊天室在线人数：" + Application["count"].ToString() + "人　　郑重声明：禁止发送一些不健康话题，否则后果自负！";

}

catch (Exception ex)

{

throw new Exception(ex.Message, ex);

}

}

##### 3．iframe 浮动框架

聊天室信息页面的结构设计主要通过 Iframe 框架实现的。浮动框架<IFRAME>是一种特殊的框架结构，它是在浏览的窗口中嵌套另外的网页文件。

例如，在 Default.aspx 页面中应用 iframe 浮动框架来嵌入内容页 MsgContent.aspx。代码如下：

<table width="100%" cellpadding="0" cellspacing="0">

<tr>

<td colspan="2" style="width: 700px">

<iframe id="msgFrame" width="100%" style="height: 440px; visibility: inherit; z-index: 1;

border-style: groove" src="MsgContent.aspx" scrolling="no" bordercolor="green"

frameborder="0"></iframe>

</td>

<td style="vertical-align: top; width: 103px" bgcolor="#d9d6e1">

<asp:ScriptManager ID="ScriptManager1" runat="server">

</asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">

<ContentTemplate>

<asp:Timer ID="Timer1" runat="server" Interval="5000" OnTick="Timer1_Tick">

</asp:Timer>

<asp:ListBox ID="lsbOnlineUser" runat="server" Height="432px" Width="101px"></asp:ListBox>

</ContentTemplate>

</asp:UpdatePanel>

</td>

</tr>

</table>

#### 实现步骤

下面介绍“制作一个简单的社区聊天室”实例的实现步骤。

##### 1．全局应用程序文件 Global.asax

（1）创建一个网站，首页默认名为 Default.aspx。

（2）在网站中添加新项，为全局应用程序类，名称为 Global.asax。

（3）在该文件的 Application_Start 事件中，初始化 Application 变量，代码如下：

void Application_Start(object sender, EventArgs e)

{

// 在应用程序启动时运行的代码

Application["count"] = 0;//统计在线人数

Application["UserName"] = "所有人";//记录在线用户的昵称

Application["Msg"] = "";//记录聊天信息

}

在 Session_Start 事件中，使 Application["count"]变量值累计 1，表示在线人数增加了 1。代码如下：

void Session_Start(object sender, EventArgs e)

{

// 在新会话启动时运行的代码

Application.Lock();

Application["count"] = int.Parse(Application["count"].ToString()) + 1;

Application.UnLock();

}

在 Session_End 事件中，首先使 Application["count"]值减 1（说明用户离线），再从 Application["UserName"]变量中去除该离线用户的昵称，并在聊天信息中标记“XX 用户离开了聊天室”。代码如下：

void Session_End(object sender, EventArgs e)

{

Application.Lock();

//在线人数减 1

Application["count"] = int.Parse(Application["count"].ToString()) - 1;

//从 Application["UserName"]变量中去除离线用户的昵称

char[] c = { ',' };

string[] un = Application["UserName"].ToString().Split(c);

string un_new = string.Empty;

for (int i = 0; i < un.Length; i++)

{

if (Session["UserName"] != un[i])

{

un_new += un[i];

}

}

Application.Set("UserName",un_new);

//将离开状态写入聊天信息

Application.Set("Msg", "" + Application["Msg"] + "<br><font color='#666666' size=2>≮" + Session["UserName"].ToString() + " 离开了聊天室>≯</</font>");

Application.UnLock();

}

##### 2．用户登录页 Logon.aspx

在用户登录页面输入昵称，就可以直接进入聊天室。如果输入的昵称与在线用户的昵称重复，就需要重新输入。

聊天室用户登录页中涉及主要控件及控件用途如表 1 所示。

表 1 聊天室登录页中主要控件及用途

控件 | ID 属性 | 主要属性 | 用途
TextBox | txtUser | 默认 | 输入用户昵称
ImageButton | imgBtnLogon | ImageUrl 属性值为 images/dl_06.jpg | 进入聊天室

在 imgBtnLogon 按钮的 Click 事件中，首先将输入的昵称与 Application["UserName"]变量中保存的在线用户昵称进行对比，如果有重复的则提示用户重新输入。否则，记录用户昵称，并在聊天信息中标识该用户进入了聊天室。代码如下：

protected void imgBtnLogon_Click(object sender, ImageClickEventArgs e)

{

bool flag = false;

string uname = txtUser.Text.Trim();//用户输入的昵称

char[] c = {','};

string[] un = Application["UserName"].ToString().Split(c);//以逗号分隔字符串，提取在线用户昵称

for (int i = 0; i < un.Length; i++)//遍历一维数组

{

//将用户输入的昵称与在线用户昵称进行比较

if (uname == un[i])

{

Response.Write("<script language='javascript' type='text/javascript'>alert('昵称重复!')</script>");

flag = true;

}

}

//用户输入的昵称可以使用

if (!flag)

{

Application.Lock();

//存储登录信息，并且进入聊天室,

Session["UserName"] = txtUser.Text.Trim();

Application["UserName"] += "," + txtUser.Text.Trim();

Application.Set("Msg", "" + Application["Msg"] + "<br><font color='#666666' size=2>≮欢迎" + Session["UserName"].ToString() + " 进入聊天室>≯</</font>");

Response.Redirect("Default.aspx");

Application.UnLock();

}

}

##### 3．聊天室主页 Default.aspx

在聊天室页面中可以实时获取在线用户列表（页面右侧部分）；可以设置用户名称的字体颜色及发送聊天信息的字体颜色；可以使用快捷键[Alt + S ]发送聊天信息；可以提示用户进入或离开聊天室的状态。在显示聊天信息区域中，当信息满屏时，信息将自动滚屏显示聊天信息。

聊天室页中涉及主要控件及控件用途如表 2 所示。

表 2 聊天室页中主要控件及用途

控件 | ID 属性 | 主要属性 | 用途
AJAX/ ScriptManager | ScriptManager1 | 默认 | 管理 AJAX 控件
AJAX/UpdatePanel | UpdatePanel1 | UpdateMode 属性值为 Conditional | 局部更新发送聊天信息
DropDownList | ddlSign | 设置 Items 属性为控件添加项列表 | 用于选择用户名称显示符号
DropDownList | ddlSign | 设置 Items 属性为控件添加项列表 | 用于设置用户名称字体颜色
DropDownList | ddlContent | 设置 Items 属性为控件添加项列表 | 用于设置聊天信息字体颜色
TextBox | txtMsg | 默认 | 输入发送的聊天信息
Button | btnSendMsg | Text 属性值为“发送 (Alt + S)” | 执行发送聊天信息命令
AJAX/UpdatePanel | UpdatePanel2 | UpdateMode 属性值为 Conditional | 局部更新在线用户
AJAX/Timer1 | Timer1 | Interval 属性值为 5000 | 每隔 5 秒获取在线用户
ListBox | lsbOnlineUser | 默认 | 显示在线用户

注意：

聊天室页面使用了局部更新的 AJAX 技术，那么在页面上添加控件时需要将控件 ID 为 ddlSign、ddlSign、ddlContent、txtMsg、btnSendMsg 放置在 UpdatePanel1 控件中。将控件 ID 为 Timer1、lsbOnlineUser 放置在 UpdatePanel2 控件中。

说明：

在 Default.aspx.cs 页面中需要引入 System.Collections 命名空间。

在 Default.aspx 页面的 Page_Load 事件下，用于实现检查用户是否已经登录，如果用于未登录，则进入到登录页面进行登录。实现代码如下：

protected void Page_Load(object sender, EventArgs e)

{

//防止非法用户直接进入聊天室，如果非法登录，则页面连接定向到登录页

if (Session["UserName"] == null)

Response.Redirect("Logon.aspx");

//聊天信息输入文本框，获得焦点

txtMsg.Focus();

}

聊天用户单击“发送”按钮，或按[Alt + S]快捷键，则发送聊天信息，聊天信息主要存储在 Application 对象中。实现代码如下：

protected void Button1_Click(object sender, EventArgs e)

{

//发送聊天信息

Application.Set("Msg", Application["Msg"] + "<br> <font color=" + ddlName.Text + " size='2px'> " + ddlSign.Text + Session["UserName"].ToString() + ddlSign.Text + " 说：</font> <font color=" + ddlContent.Text + " size='2px'> " + txtMsg.Text + " </font><font size='2px'>「" + DateTime.Now.ToString() + "」</font>");

//清空聊天信息输入文本框

txtMsg.Text = "";

}

在 AJAX 中的 Timer 控件的 Tick 事件下，主要完成每过 5 秒中获取聊天室当前在线用户，并显示在 ListBox 中。实现代码如下：

protected void Timer1_Tick(object sender, EventArgs e)

{

ArrayList arr = new ArrayList();

char[] c = { ',' };

string[] un = Application["UserName"].ToString().Split(c);//以逗号分隔字符串，提取在线用户昵称

for (int i = 0; i < un.Length; i++)

{

arr.Add(new ListItem(un[i],un[i]));

}

lsbOnlineUser.DataSource = arr;//为 ListBox 控件设置数据源

lsbOnlineUser.DataBind();

}

##### 4．内容页 MsgContent.aspx

显示聊天信息内容页是嵌入在聊天室中用于显示聊天信息内容和聊天用户的当前状态的。该页显示的所有信息都是从 Application 对象中获取。

聊天信息内容页中涉及主要控件及控件用途如表 3 所示。

表 3 聊天信息内容页中主要控件及用途

控件 | ID 属性 | 主要属性 | 用途
AJAX/ ScriptManager | ScriptManager1 | 默认 | 管理 AJAX 控件
AJAX/UpdatePanel | UpdatePanel1 | 默认 | 局部更新聊天信息
AJAX/Timer1 | Timer1 | Interval 属性值为 2000 | 每隔 2 秒更新聊天信息
Label | lblMsg | 默认 | 显示所有聊天信息
Label | lblcount | 默认 | 显示当前用户在线个数

聊天信息内容页主要实时显示聊天室的所有聊天信息，在此使用 AJAX 中 Timer 控件的 Tick 事件下，每隔 2 秒就获取最新的聊天信息，并且显示统计的在线人数。实现代码如下：

protected void Timer1_Tick(object sender, EventArgs e)

{

try

{

//获取聊天信息

lblMsg.Text = Application["Msg"].ToString();

//统计在线人数

lblcount.Text = "聊天室在线人数：" + Application["count"].ToString() + "人　　郑重声明：禁止发送一些不健康话题，否则后果自负！";

}

catch (Exception ex)

{

throw new Exception(ex.Message, ex);

}

}