基于atlas的聊天室设计(有源码)
2007-06-12 14:19 Brush 阅读(609) 评论(4) 编辑 收藏 举报 来博客园有一段时间了,觉得这里高手蛮多的,也能学到不少东西。
最近我在搞一个B/S结构下的聊天室,用到了atlas技术,其中也有点小问题,就是输入框的焦点会在局部刷新的时候丢失。望各高手不吝赐教。
首先说一下我的设计思路:
在B/S下的聊天室,因为服务端不能主动向客户端发送消息(请求),只能响应客户端发送过来的请求,故聊天室的聊天数据的获取只能是主动形式的,即客户端定期向服务端请求最新聊天数据,然后显示在页面上。这样就不得不涉及到页面的频繁刷新。在刷新方面我用了atlas局部刷新技术。
数据存取方面我使用了NHibernate技术。
此聊天室是一个功能很简单的聊天室,源码如下:
页面部分:
1<%@ Page Language="C#" AutoEventWireup="true" CodeFile="zDefault.aspx.cs" Inherits="_Default" validateRequest=false %>
2
3<html xmlns="http://www.w3.org/1999/xhtml">
4<script type="text/javascript" language="JavaScript">
5function document.onkeydown()
6{
7 var e=event.srcElement;
8 if((event.keyCode==13) && event.ctrlKey)
9 {
10 document.getElementById("btnSend").click();
11 return false;
12 }
13};
14function beforeunloads()
15{
16// if(confirm('确认退出《刷刷聊天室》?') == false)
17// {
18//// document.getElementById("btnExit").click();
19// cancel=1;
20// return false;
21// }
22// cancel=1;
23// return true;
24if (event.clientX>document.body.clientWidth && event.clientY<0 || event.altKey)
25 {
26 window.event.returnValue="确认退出《刷刷聊天室》?";
27 }
28};
29 </script>
30<head runat="server">
31 <title>刷刷聊天室</title>
32</head>
33<body onbeforeunload="javascript:beforeunloads();">
34 <form id="form1" runat="server">
35 <atlas:ScriptManager ID="ScriptManager1" EnablePartialRendering=true runat="server" />
36 <atlas:UpdateProgress ID=upup1 runat=server>
37
38 <ProgressTemplate>
39 <label id="aaa" runat=server>正在更新信息</label><asp:TextBox ID="TextBox1" runat="server">aaa</asp:TextBox>
40 </ProgressTemplate>
41 </atlas:UpdateProgress>
42 <%-- <atlas:TimerControl ID=tt1 runat=server OnTick=btnRefresh_Click EnableViewState=true Interval=5000></atlas:TimerControl>--%>
43
44 <span style="color: mediumblue"><strong>欢迎进入刷刷聊天室</strong><span style="color: red"></span><span style="color: red"></span><strong>
45 <asp:Button ID="btnExit" runat="server" OnClientClick="return confirm('确认退出刷刷聊天室?')" OnClick="btnExit_Click" Text="退 出" /></strong></span><br />
46
47
48 <atlas:UpdatePanel ID="up1" runat="server" RenderMode=Block Mode="conditional">
49 <ContentTemplate>
50 <strong><span style="color: #0000cd">(</span></strong><span style="color: red">当前共<asp:Label
51 ID="lblNum" runat="server"></asp:Label>人<strong><span style="color: #0000cd">)</span><asp:Button
52 ID="btnRefresh" runat="server" OnClick="btnRefresh_Click" Text="0" Width="100px" /><br />
53 <br />
54 </strong></span> 我的呢称:<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
55 <asp:TextBox ID="txtName" runat="server"></asp:TextBox>
56 <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="修 改" TabIndex="1" />
57 <br />
58 信息序号:<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
59
60 <div id="divMain" runat="server" style="border-right: blue 1px solid; padding-right: 5px;
61 border-top: blue 1px solid; padding-left: 5px; font-size: 12px; padding-bottom: 5px;
62 overflow: auto; border-left: blue 1px solid; width: 735px; padding-top: 5px; word-break:break-all;
63 border-bottom: blue 1px solid; height: 223px">
64 </div>
65
66 <asp:Button ID="btnClear" runat="server" OnClick="btnClear_Click" Text="清 屏" /> <br />
67 <br />
68 对<asp:DropDownList ID="ddlPerson" runat="server">
69 </asp:DropDownList>说:<br />
70
71 <asp:TextBox ID="txtInput" runat="server" Height="103px" TextMode="MultiLine" Width="534px"></asp:TextBox><br />
72
73 <asp:Button ID="btnSend" runat="server" OnClick="btnSend_Click" Text="发 送(Ctrl+Enter)" />
74 <%--<a href=Default.aspx target=_blank>aa</a>--%>
75 <br />
76 </ContentTemplate>
77 <Triggers>
78 <atlas:ControlEventTrigger ControlID="btnSend" EventName="Click" />
79 <atlas:ControlEventTrigger ControlID="Button1" EventName="Click" />
80 <%--<atlas:ControlEventTrigger ControlID="btnRefresh" EventName="Click" />--%>
81 <atlas:ControlEventTrigger ControlID="btnClear" EventName="Click" />
82 <atlas:ControlValueTrigger ControlID="Label1" PropertyName="Text" />
83 <atlas:ControlValueTrigger ControlID="Label2" PropertyName="Text" />
84 <atlas:ControlValueTrigger ControlID="txtInput" PropertyName="Text" />
85 <atlas:ControlValueTrigger ControlID="ddlPerson" PropertyName="SelectedIndex" />
86 </Triggers>
87 </atlas:UpdatePanel>
88
89 </form>
90</body>
91<script language=javascript type="text/javascript">
92//var txtabc = "txtInput";
93//var tempabc = document.getElementById("txtInput");
94// tempabc.onfocus() = function() { txtabc = "txtInput";};
95// tempabc = document.getElementById("txtName");
96// tempabc.onfocus() = function() { txtabc = "txtName";};
97//function settxtabc(tt)
98//{
99// txtabc = tt;
100//}
101function mainRefresha()
102{
103 // 记录光标丢失位置
104 document.getElementById("btnRefresh").click();
105 // 恢复原光标位置
106 document.getElementById("txtInput").innerText = "abc";
107 return true;
108};
109function northsnow()
110{
111// document.getElementById(txtabc).focus();
112 divMain.scrollTop=divMain.scrollHeight;
113 setTimeout("mainRefresha()",5000);
114};
115//setInterval('northsnow()',100);
116setTimeout("northsnow()",1);
117</script>
118</html>
2
3<html xmlns="http://www.w3.org/1999/xhtml">
4<script type="text/javascript" language="JavaScript">
5function document.onkeydown()
6{
7 var e=event.srcElement;
8 if((event.keyCode==13) && event.ctrlKey)
9 {
10 document.getElementById("btnSend").click();
11 return false;
12 }
13};
14function beforeunloads()
15{
16// if(confirm('确认退出《刷刷聊天室》?') == false)
17// {
18//// document.getElementById("btnExit").click();
19// cancel=1;
20// return false;
21// }
22// cancel=1;
23// return true;
24if (event.clientX>document.body.clientWidth && event.clientY<0 || event.altKey)
25 {
26 window.event.returnValue="确认退出《刷刷聊天室》?";
27 }
28};
29 </script>
30<head runat="server">
31 <title>刷刷聊天室</title>
32</head>
33<body onbeforeunload="javascript:beforeunloads();">
34 <form id="form1" runat="server">
35 <atlas:ScriptManager ID="ScriptManager1" EnablePartialRendering=true runat="server" />
36 <atlas:UpdateProgress ID=upup1 runat=server>
37
38 <ProgressTemplate>
39 <label id="aaa" runat=server>正在更新信息</label><asp:TextBox ID="TextBox1" runat="server">aaa</asp:TextBox>
40 </ProgressTemplate>
41 </atlas:UpdateProgress>
42 <%-- <atlas:TimerControl ID=tt1 runat=server OnTick=btnRefresh_Click EnableViewState=true Interval=5000></atlas:TimerControl>--%>
43
44 <span style="color: mediumblue"><strong>欢迎进入刷刷聊天室</strong><span style="color: red"></span><span style="color: red"></span><strong>
45 <asp:Button ID="btnExit" runat="server" OnClientClick="return confirm('确认退出刷刷聊天室?')" OnClick="btnExit_Click" Text="退 出" /></strong></span><br />
46
47
48 <atlas:UpdatePanel ID="up1" runat="server" RenderMode=Block Mode="conditional">
49 <ContentTemplate>
50 <strong><span style="color: #0000cd">(</span></strong><span style="color: red">当前共<asp:Label
51 ID="lblNum" runat="server"></asp:Label>人<strong><span style="color: #0000cd">)</span><asp:Button
52 ID="btnRefresh" runat="server" OnClick="btnRefresh_Click" Text="0" Width="100px" /><br />
53 <br />
54 </strong></span> 我的呢称:<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
55 <asp:TextBox ID="txtName" runat="server"></asp:TextBox>
56 <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="修 改" TabIndex="1" />
57 <br />
58 信息序号:<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
59
60 <div id="divMain" runat="server" style="border-right: blue 1px solid; padding-right: 5px;
61 border-top: blue 1px solid; padding-left: 5px; font-size: 12px; padding-bottom: 5px;
62 overflow: auto; border-left: blue 1px solid; width: 735px; padding-top: 5px; word-break:break-all;
63 border-bottom: blue 1px solid; height: 223px">
64 </div>
65
66 <asp:Button ID="btnClear" runat="server" OnClick="btnClear_Click" Text="清 屏" /> <br />
67 <br />
68 对<asp:DropDownList ID="ddlPerson" runat="server">
69 </asp:DropDownList>说:<br />
70
71 <asp:TextBox ID="txtInput" runat="server" Height="103px" TextMode="MultiLine" Width="534px"></asp:TextBox><br />
72
73 <asp:Button ID="btnSend" runat="server" OnClick="btnSend_Click" Text="发 送(Ctrl+Enter)" />
74 <%--<a href=Default.aspx target=_blank>aa</a>--%>
75 <br />
76 </ContentTemplate>
77 <Triggers>
78 <atlas:ControlEventTrigger ControlID="btnSend" EventName="Click" />
79 <atlas:ControlEventTrigger ControlID="Button1" EventName="Click" />
80 <%--<atlas:ControlEventTrigger ControlID="btnRefresh" EventName="Click" />--%>
81 <atlas:ControlEventTrigger ControlID="btnClear" EventName="Click" />
82 <atlas:ControlValueTrigger ControlID="Label1" PropertyName="Text" />
83 <atlas:ControlValueTrigger ControlID="Label2" PropertyName="Text" />
84 <atlas:ControlValueTrigger ControlID="txtInput" PropertyName="Text" />
85 <atlas:ControlValueTrigger ControlID="ddlPerson" PropertyName="SelectedIndex" />
86 </Triggers>
87 </atlas:UpdatePanel>
88
89 </form>
90</body>
91<script language=javascript type="text/javascript">
92//var txtabc = "txtInput";
93//var tempabc = document.getElementById("txtInput");
94// tempabc.onfocus() = function() { txtabc = "txtInput";};
95// tempabc = document.getElementById("txtName");
96// tempabc.onfocus() = function() { txtabc = "txtName";};
97//function settxtabc(tt)
98//{
99// txtabc = tt;
100//}
101function mainRefresha()
102{
103 // 记录光标丢失位置
104 document.getElementById("btnRefresh").click();
105 // 恢复原光标位置
106 document.getElementById("txtInput").innerText = "abc";
107 return true;
108};
109function northsnow()
110{
111// document.getElementById(txtabc).focus();
112 divMain.scrollTop=divMain.scrollHeight;
113 setTimeout("mainRefresha()",5000);
114};
115//setInterval('northsnow()',100);
116setTimeout("northsnow()",1);
117</script>
118</html>
后.cs部分:
1public partial class _Default : System.Web.UI.Page
2{
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 if (!IsPostBack)
6 {
7 if (btnRefresh.Text == "0")
8 {
9 //txtInput.Attributes.Add("onclick", "settxtabc('txtInput')");
10 //txtName.Attributes.Add("onclick", "settxtabc('txtName')");
11 ViewState["id"] = VCwMess.GetLastID().ToString();
12 btnRefresh.Text = "1";
13 Label2.Text = "游客" + DateTime.Now.ToString("HHmmssfff");
14 AddUser(Label2.Text);
15 ViewState["userRefresh"] = DateTime.Now;
16 RefreshUsers(); // 刷新用户列表
17 }
18 }
19 }
20
21 // 修改呢称
22 protected void Button1_Click(object sender, EventArgs e)
23 {
24 //System.Threading.Thread.Sleep(2000); // 网络延迟
25 CwUser cc = VCwUser.GetById(((CwUser)(ViewState["user"])).Id);
26 cc.Name = txtName.Text;
27 cc.Lasttime = DateTime.Now;
28 VCwUser.SaveOrUpdate(cc);
29 ViewState["user"] = cc;
30 AddMess(3, Label2.Text, txtName.Text, cc.Id.ToString(), false);
31 Label2.Text = txtName.Text;
32 }
33
34 // 发送信息
35 protected void btnSend_Click(object sender, EventArgs e)
36 {
37 //System.Threading.Thread.Sleep(2000); // 网络延迟
38 //AddMess(0, Label2.Text, ddlPerson.SelectedValue, txtInput.Text, true);
39 CwUser cc = VCwUser.GetById(((CwUser)(ViewState["user"])).Id);
40 cc.Lasttime = DateTime.Now;
41 VCwUser.SaveOrUpdate(cc);
42 ViewState["user"] = cc;
43 AddMess(0, Label2.Text, ddlPerson.SelectedItem.Text, txtInput.Text, true);
44 //this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "setTimeout('northsnow()',100);", true);
45 //this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "document.getElementById('txtInput').focus();", true);
46 //txtName.Focus();
47 //txtInput.Focus();
48 }
49
50 // 设置/刷新聊天窗口显示
51 private void SetMain()
52 {
53 //IList list = VCwMess.GetList(DateTime.Now.AddSeconds(-10));
54 int id = int.Parse(ViewState["id"].ToString());
55 IList list = VCwMess.GetList(id);
56
57 foreach (CwMess cc in list)
58 {
59 if (cc.Id > id) // 表明此信息未被加载
60 {
61 ShowMess(cc); // 加载此信息
62 }
63 }
64 Label1.Text = ViewState["id"].ToString();
65 this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "setTimeout(\"northsnow()\",1);", true);
66 //this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "setTimeout(\"northsnow('" + ViewState["txt"].ToString() + "')\",1);", true);
67 //this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "document.all('txtInput').focus();", true);
68 //this.ClientScript.RegisterStartupScript(typeof(Microsoft.Web.UI.UpdatePanel), "yimi1", "document.getElementById('txtInput').focus();", true);
69 //Response.Write("<script>divMain.scrollTop=divMain.scrollHeight;</script>");
70 }
71
72 // 刷新用户列表(在用户登录之后)
73 private void RefreshUsers()
74 {
75 ddlPerson.Items.Clear();
76 ddlPerson.Items.Add(new ListItem("所有人", "0"));
77
78 IList list = VCwUser.GetList(DateTime.Now.AddMinutes(-10)); // 读取10分钟内都在发言的名单(某人关闭页面后,10分钟才能体现出来)
79 lblNum.Text = list.Count.ToString();
80 int id = ((CwUser)(ViewState["user"])).Id;
81 foreach (CwUser cc in list)
82 {
83 if (cc.Id != id) // 下拉菜单中只添加其它人
84 {
85 ddlPerson.Items.Add(new ListItem(cc.Name, cc.Id.ToString()));
86 }
87 }
88 }
89
90 // 刷新聊天信息
91 protected void btnRefresh_Click(object sender, EventArgs e)
92 {
93 System.Threading.Thread.Sleep(2000); // 网络延迟
94 SetMain();
95 if (ViewState["userRefresh"] == null)
96 {
97 ViewState["userRefresh"] = DateTime.Now;
98 RefreshUsers(); // 刷新用户列表
99 }
100 else
101 {
102 DateTime dt = (DateTime)(ViewState["userRefresh"]);
103 if (dt.AddMinutes(5) < DateTime.Now) // 五分钟刷新一次列表(同时对无操作的本用户更新状态)
104 {
105 // 对无操作的本用户更新状态
106 CwUser cc = VCwUser.GetById(((CwUser)(ViewState["user"])).Id);
107 cc.Name = txtName.Text;
108 cc.Lasttime = DateTime.Now;
109 VCwUser.SaveOrUpdate(cc);
110 ViewState["user"] = cc;
111
112 ViewState["userRefresh"] = DateTime.Now;
113 RefreshUsers(); // 刷新用户列表
114 }
115 }
116 }
117
118 // 添加一条信息
119 private void AddMess(int type, string from, string to, string mess, bool needClear)
120 {
121 CwMess cc = new CwMess();
122 cc.Name1 = from;
123 cc.Name2 = to;
124 cc.Inf = mess;
125 cc.AddTime = DateTime.Now;
126 cc.Type = type; // 一般消息
127 if (needClear) // 需要清除输入框
128 {
129 txtInput.Text = "";
130 }
131
132 VCwMess.SaveOrUpdate(cc);
133 SetMain();
134 }
135
136 // 添加一个用户
137 private void AddUser(string name)
138 {
139 CwUser cc = new CwUser();
140 cc.Name = Label2.Text;
141 cc.State = 1;
142 VCwUser.SaveOrUpdate(cc);
143 ViewState["user"] = cc;
144 AddMess(2, cc.Name, cc.Id.ToString(), "", false);
145
146
147 }
148
149 // 显示一条信息
150 private void ShowMess(CwMess cc)
151 {
152 string temp;
153 switch (cc.Type)
154 {
155 case 0: // 一般消息
156 temp = "[<font color=blue>" + cc.Name1 + "</font>] 对 [<font color=blue>" + cc.Name2 + "]</font> 说:";
157 temp += "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
158 temp += cc.Inf;
159 temp += "<br>";
160 break;
161 case 1: // 系统公告
162 temp = "<br>[<b><font color=red>系统公告</font></b>]" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
163 temp += "<font color=red>" + cc.Inf + "</font><br>";
164 break;
165 case 2: // 进入聊天室
166 temp = "<br>[<b><font color=red>系统公告</font></b>]" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
167 temp += "欢迎[<font color=blue>" + cc.Name1 + "</font>] 进入刷刷聊天室!<br>";
168 if(((CwUser)(ViewState["user"])).Id.ToString() != cc.Name2) // 不是本人的消息
169 {
170 ddlPerson.Items.Add(new ListItem(cc.Name1, cc.Name2));
171 int num = ddlPerson.Items.Count + 1;
172 lblNum.Text = num.ToString();
173 }
174 break;
175 case 3: // 更改呢称
176 temp = "<br>[<b><font color=red>系统公告</font></b>]" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
177 temp += "[<font color=blue>" + cc.Name1 + "</font>] 更改呢称为:[<font color=blue>" + cc.Name2 + "</font>]<br>";
178 if (((CwUser)(ViewState["user"])).Id.ToString() != cc.Inf) // 不是本人的消息
179 {
180 for (int i = 0; i < ddlPerson.Items.Count; i++)
181 {
182 if (ddlPerson.Items[i].Value == cc.Inf)
183 {
184 ddlPerson.Items.RemoveAt(i);
185 ddlPerson.Items.Add(new ListItem(cc.Name2, cc.Inf));
186 break;
187 }
188 }
189 }
190 break;
191 case 4: // 离开聊天室
192 temp = "<br>[<b><font color=red>系统公告</font></b>]" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
193 temp += "[<font color=blue>" + cc.Name1 + "</font>] 离开了。<br>";
194 lblNum.Text = ddlPerson.Items.Count.ToString();
195 ddlPerson.Items.Remove(ddlPerson.Items.FindByText(cc.Name1)); // 从下拉列表中移除
196 break;
197 default:
198 temp = "<b><font color=red>系统出错!请联系管理员!</font></b>" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br>";
199 break;
200 }
201 divMain.InnerHtml += temp;
202 ViewState["id"] = cc.Id;
203 }
204
205 // 退出聊天室
206 protected void btnExit_Click(object sender, EventArgs e)
207 {
208 string url = "Logout.aspx?id=" + ((CwUser)(ViewState["user"])).Id.ToString();
209 Response.Write("<script>location.href='" + url + "';self.opener='meizz';self.close();</script>");
210 }
211
212 // 清屏
213 protected void btnClear_Click(object sender, EventArgs e)
214 {
215 //System.Threading.Thread.Sleep(2000); // 网络延迟
216 divMain.InnerHtml = "";
217 }
218}
2{
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 if (!IsPostBack)
6 {
7 if (btnRefresh.Text == "0")
8 {
9 //txtInput.Attributes.Add("onclick", "settxtabc('txtInput')");
10 //txtName.Attributes.Add("onclick", "settxtabc('txtName')");
11 ViewState["id"] = VCwMess.GetLastID().ToString();
12 btnRefresh.Text = "1";
13 Label2.Text = "游客" + DateTime.Now.ToString("HHmmssfff");
14 AddUser(Label2.Text);
15 ViewState["userRefresh"] = DateTime.Now;
16 RefreshUsers(); // 刷新用户列表
17 }
18 }
19 }
20
21 // 修改呢称
22 protected void Button1_Click(object sender, EventArgs e)
23 {
24 //System.Threading.Thread.Sleep(2000); // 网络延迟
25 CwUser cc = VCwUser.GetById(((CwUser)(ViewState["user"])).Id);
26 cc.Name = txtName.Text;
27 cc.Lasttime = DateTime.Now;
28 VCwUser.SaveOrUpdate(cc);
29 ViewState["user"] = cc;
30 AddMess(3, Label2.Text, txtName.Text, cc.Id.ToString(), false);
31 Label2.Text = txtName.Text;
32 }
33
34 // 发送信息
35 protected void btnSend_Click(object sender, EventArgs e)
36 {
37 //System.Threading.Thread.Sleep(2000); // 网络延迟
38 //AddMess(0, Label2.Text, ddlPerson.SelectedValue, txtInput.Text, true);
39 CwUser cc = VCwUser.GetById(((CwUser)(ViewState["user"])).Id);
40 cc.Lasttime = DateTime.Now;
41 VCwUser.SaveOrUpdate(cc);
42 ViewState["user"] = cc;
43 AddMess(0, Label2.Text, ddlPerson.SelectedItem.Text, txtInput.Text, true);
44 //this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "setTimeout('northsnow()',100);", true);
45 //this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "document.getElementById('txtInput').focus();", true);
46 //txtName.Focus();
47 //txtInput.Focus();
48 }
49
50 // 设置/刷新聊天窗口显示
51 private void SetMain()
52 {
53 //IList list = VCwMess.GetList(DateTime.Now.AddSeconds(-10));
54 int id = int.Parse(ViewState["id"].ToString());
55 IList list = VCwMess.GetList(id);
56
57 foreach (CwMess cc in list)
58 {
59 if (cc.Id > id) // 表明此信息未被加载
60 {
61 ShowMess(cc); // 加载此信息
62 }
63 }
64 Label1.Text = ViewState["id"].ToString();
65 this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "setTimeout(\"northsnow()\",1);", true);
66 //this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "setTimeout(\"northsnow('" + ViewState["txt"].ToString() + "')\",1);", true);
67 //this.ClientScript.RegisterClientScriptBlock(this.GetType(), "yimi", "document.all('txtInput').focus();", true);
68 //this.ClientScript.RegisterStartupScript(typeof(Microsoft.Web.UI.UpdatePanel), "yimi1", "document.getElementById('txtInput').focus();", true);
69 //Response.Write("<script>divMain.scrollTop=divMain.scrollHeight;</script>");
70 }
71
72 // 刷新用户列表(在用户登录之后)
73 private void RefreshUsers()
74 {
75 ddlPerson.Items.Clear();
76 ddlPerson.Items.Add(new ListItem("所有人", "0"));
77
78 IList list = VCwUser.GetList(DateTime.Now.AddMinutes(-10)); // 读取10分钟内都在发言的名单(某人关闭页面后,10分钟才能体现出来)
79 lblNum.Text = list.Count.ToString();
80 int id = ((CwUser)(ViewState["user"])).Id;
81 foreach (CwUser cc in list)
82 {
83 if (cc.Id != id) // 下拉菜单中只添加其它人
84 {
85 ddlPerson.Items.Add(new ListItem(cc.Name, cc.Id.ToString()));
86 }
87 }
88 }
89
90 // 刷新聊天信息
91 protected void btnRefresh_Click(object sender, EventArgs e)
92 {
93 System.Threading.Thread.Sleep(2000); // 网络延迟
94 SetMain();
95 if (ViewState["userRefresh"] == null)
96 {
97 ViewState["userRefresh"] = DateTime.Now;
98 RefreshUsers(); // 刷新用户列表
99 }
100 else
101 {
102 DateTime dt = (DateTime)(ViewState["userRefresh"]);
103 if (dt.AddMinutes(5) < DateTime.Now) // 五分钟刷新一次列表(同时对无操作的本用户更新状态)
104 {
105 // 对无操作的本用户更新状态
106 CwUser cc = VCwUser.GetById(((CwUser)(ViewState["user"])).Id);
107 cc.Name = txtName.Text;
108 cc.Lasttime = DateTime.Now;
109 VCwUser.SaveOrUpdate(cc);
110 ViewState["user"] = cc;
111
112 ViewState["userRefresh"] = DateTime.Now;
113 RefreshUsers(); // 刷新用户列表
114 }
115 }
116 }
117
118 // 添加一条信息
119 private void AddMess(int type, string from, string to, string mess, bool needClear)
120 {
121 CwMess cc = new CwMess();
122 cc.Name1 = from;
123 cc.Name2 = to;
124 cc.Inf = mess;
125 cc.AddTime = DateTime.Now;
126 cc.Type = type; // 一般消息
127 if (needClear) // 需要清除输入框
128 {
129 txtInput.Text = "";
130 }
131
132 VCwMess.SaveOrUpdate(cc);
133 SetMain();
134 }
135
136 // 添加一个用户
137 private void AddUser(string name)
138 {
139 CwUser cc = new CwUser();
140 cc.Name = Label2.Text;
141 cc.State = 1;
142 VCwUser.SaveOrUpdate(cc);
143 ViewState["user"] = cc;
144 AddMess(2, cc.Name, cc.Id.ToString(), "", false);
145
146
147 }
148
149 // 显示一条信息
150 private void ShowMess(CwMess cc)
151 {
152 string temp;
153 switch (cc.Type)
154 {
155 case 0: // 一般消息
156 temp = "[<font color=blue>" + cc.Name1 + "</font>] 对 [<font color=blue>" + cc.Name2 + "]</font> 说:";
157 temp += "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
158 temp += cc.Inf;
159 temp += "<br>";
160 break;
161 case 1: // 系统公告
162 temp = "<br>[<b><font color=red>系统公告</font></b>]" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
163 temp += "<font color=red>" + cc.Inf + "</font><br>";
164 break;
165 case 2: // 进入聊天室
166 temp = "<br>[<b><font color=red>系统公告</font></b>]" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
167 temp += "欢迎[<font color=blue>" + cc.Name1 + "</font>] 进入刷刷聊天室!<br>";
168 if(((CwUser)(ViewState["user"])).Id.ToString() != cc.Name2) // 不是本人的消息
169 {
170 ddlPerson.Items.Add(new ListItem(cc.Name1, cc.Name2));
171 int num = ddlPerson.Items.Count + 1;
172 lblNum.Text = num.ToString();
173 }
174 break;
175 case 3: // 更改呢称
176 temp = "<br>[<b><font color=red>系统公告</font></b>]" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
177 temp += "[<font color=blue>" + cc.Name1 + "</font>] 更改呢称为:[<font color=blue>" + cc.Name2 + "</font>]<br>";
178 if (((CwUser)(ViewState["user"])).Id.ToString() != cc.Inf) // 不是本人的消息
179 {
180 for (int i = 0; i < ddlPerson.Items.Count; i++)
181 {
182 if (ddlPerson.Items[i].Value == cc.Inf)
183 {
184 ddlPerson.Items.RemoveAt(i);
185 ddlPerson.Items.Add(new ListItem(cc.Name2, cc.Inf));
186 break;
187 }
188 }
189 }
190 break;
191 case 4: // 离开聊天室
192 temp = "<br>[<b><font color=red>系统公告</font></b>]" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br> ";
193 temp += "[<font color=blue>" + cc.Name1 + "</font>] 离开了。<br>";
194 lblNum.Text = ddlPerson.Items.Count.ToString();
195 ddlPerson.Items.Remove(ddlPerson.Items.FindByText(cc.Name1)); // 从下拉列表中移除
196 break;
197 default:
198 temp = "<b><font color=red>系统出错!请联系管理员!</font></b>" + "<font color=gray>" + cc.AddTime.ToString("HH:mm:ss") + "<br>";
199 break;
200 }
201 divMain.InnerHtml += temp;
202 ViewState["id"] = cc.Id;
203 }
204
205 // 退出聊天室
206 protected void btnExit_Click(object sender, EventArgs e)
207 {
208 string url = "Logout.aspx?id=" + ((CwUser)(ViewState["user"])).Id.ToString();
209 Response.Write("<script>location.href='" + url + "';self.opener='meizz';self.close();</script>");
210 }
211
212 // 清屏
213 protected void btnClear_Click(object sender, EventArgs e)
214 {
215 //System.Threading.Thread.Sleep(2000); // 网络延迟
216 divMain.InnerHtml = "";
217 }
218}
需要创建的表:
CREATE TABLE [dbo].[mess] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[type] [int] NULL ,
[inf] [text] COLLATE Chinese_PRC_CI_AS NULL ,
[name1] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[name2] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[addtime] [datetime] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[users] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[lasttime] [datetime] NULL ,
[state] [int] NULL
) ON [PRIMARY]
GO
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[type] [int] NULL ,
[inf] [text] COLLATE Chinese_PRC_CI_AS NULL ,
[name1] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[name2] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[addtime] [datetime] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[users] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[lasttime] [datetime] NULL ,
[state] [int] NULL
) ON [PRIMARY]
GO