2.打开VS2008,创建一个.NET Framework 3.5的ASP.NET网站。开发语言是:C#
3.建一个登录页,注册页以及登录用户和密码的加密就免了,Just for fun!不考虑那么多了。
4.创建聊天页,效果图及页面元素说明如下:
现在,界面上的完成了,该进入代码阶段了
首先关注下,整个聊天室的工作流程:
1.首先,打开web.config,加入用户验证的东东
50 <authentication mode="Forms">
51 <forms name=".ASPXAUTH" loginUrl="Default.aspx"/>
52 </authentication>
53
54 <authorization>
55 <deny users="?" />
56 </authorization>
2.用户登录后由登录页跳转到聊天页时,用户名及密码用Session来保存。这里在跳转后,由于之前假定用户只有一个聊天室,
因此跳转后,会进入聊天室为"room1"的聊天页。如果存在多个聊天室,那么你可以再加一个聊天室的列表页,让用户进入到 这里,由他选择进入哪个聊天室。登录的代码如下:
13 protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
14 {
15 LinqChatDataContext db = new LinqChatDataContext();
16
17 var user = (from u in db.Users
18 where u.Username == Login1.UserName
19 && u.Password == Login1.Password
20 select u).SingleOrDefault();
21
22 if (user != null)
23 {
24 e.Authenticated = true;
25 Session["ChatUserID"] = user.UserID;
26 Session["ChatUsername"] = user.Username;
27 }
28 else
29 {
30 e.Authenticated = false;
31 }
32 }
33
34 protected void Login1_LoggedIn(object sender, EventArgs e)
35 {
36 Response.Redirect("Chatroom.aspx?roomId=1");
37 }
3.根据接收到的roomId的值,来确定聊天室的名字,已经聊天室的相关信息,比如成员,聊天记录等等
16 // for simplity's sake we're going to assume that a
17 // roomId was passed in the query string and that
18 // it is an integer
19 // note: in reality you would check if the roomId is empty
20 // and is an integer
21 string roomId = (string)Request["roomId"];
22 lblRoomId.Text = roomId;
4.为了通知其他用户,该用户已进入聊天室,所以建立了LoggedInUser 来记录聊天室的一些信息。通过
这个表,我们可以获取聊天室的所有成员及信息。这个操作的代码如下:
26 this.InsertMessage(ConfigurationManager.AppSettings["ChatLoggedInText"] + " " + DateTime.Now.ToString());
5.InsertMessage的具体代码如下:
74 private void InsertMessage(string text)
75 {
76 LinqChatDataContext db = new LinqChatDataContext();
77
78 Message message = new Message();
79 message.RoomID = Convert.ToInt32(lblRoomId.Text);
80 message.UserID= Convert.ToInt32(Session["ChatUserID"]);
81
82 if (String.IsNullOrEmpty(text))
83 {
84 message.Text = txtMessage.Text.Replace("<", "");
85 message.Color = ddlColor.SelectedValue;
86 }
87 else
88 {
89 message.Text = text;
90 message.Color = "gray";
91 }
92
93 message.ToUserID = null; // in the future, we will use this value for private messages
94 message.TimeStamp = DateTime.Now;
95 db.Messages.InsertOnSubmit(message);
96 db.SubmitChanges();
97 }
同时在web.config里加入以下代码:
24 <appSettings>
25 <add key="ChatLoggedInText" value="Just logged in!"/>
26 </appSettings>
6.完成了新增Message记录后,接下来是完成显示Message的功能了:
148 /// <summary>
149 /// Get the last 20 messages for this room
150 /// </summary>
151 private void GetMessages() 152 {
153 LinqChatDataContext db = new LinqChatDataContext(); 154
155 var messages = (from m in db.Messages
156 where m.RoomID == Convert.ToInt32(lblRoomId.Text)
157 orderby m.TimeStamp descending
158 select m).Take(20).OrderBy(m => m.TimeStamp);
159
160 if (messages != null)
161 {
162 StringBuilder sb = new StringBuilder();
163 int ctr = 0; // toggle counter for alternating color
164
165 foreach (var message in messages)
166 {
167 // alternate background color on messages
168 if (ctr == 0)
169 {
170 sb.Append("<div style='padding: 10px;'>");
171 ctr = 1;
172 }
173 else
174 {
175 sb.Append("<div style='background-color: #EFEFEF; padding: 10px;'>");
176 ctr = 0;
177 }
178
179 if (message.User.Sex.ToString().ToLower() == "m")
180 sb.Append("<img src='Images/manIcon.gif' style='vertical-align:middle' alt=''> " + message.Text + "</div>");
181 else
182 sb.Append("<img src='Images/womanIcon.gif' style='vertical-align:middle' alt=''> " + message.Text + "</div>");
183 }
184
185 litMessages.Text = sb.ToString();
186 }
187 }
7.当用户登录该聊天室时,右侧的用户列表区必须显示当前聊天室参与的的用户。当你选择某位用户时,你可以和他私聊。
99 private void GetLoggedInUsers()
100 {
101 LinqChatDataContext db = new LinqChatDataContext();
102
103 // let's check if this authenticated user exist in the
104 // LoggedInUser table (means user is logged-in to this room)
105 var user = (from u in db.LoggedInUsers
106 where u.UserID == Convert.ToInt32(Session["ChatUserID"])
107 && u.RoomID == Convert.ToInt32(lblRoomId.Text)
108 select u).SingleOrDefault();
109
110 // if user does not exist in the LoggedInUser table
111 // then let's add/insert the user to the table
112 if (user == null)
113 {
114 LoggedInUser loggedInUser = new LoggedInUser();
115 loggedInUser.UserID = Convert.ToInt32(Session["ChatUserID"]);
116 loggedInUser.RoomID = Convert.ToInt32(lblRoomId.Text);
117 db.LoggedInUsers.InsertOnSubmit(loggedInUser);
118 db.SubmitChanges();
119 }
120
121 string userIcon;
122 StringBuilder sb = new StringBuilder();
123
124 // get all logged in users to this room
125 var loggedInUsers = from l in db.LoggedInUsers
126 where l.RoomID == Convert.ToInt32(lblRoomId.Text)
127 select l;
128
129 // list all logged in chat users in the user list
130 foreach (var loggedInUser in loggedInUsers)
131 {
132 // show user icon based on sex
133 if (loggedInUser.User.Sex.ToString().ToLower() == "m")
134 userIcon = "<img src='Images/manIcon.gif' style='vertical-align:middle' alt=''> ";
135 else
136 userIcon = "<img src='Images/womanIcon.gif' style='vertical-align:middle' alt=''> ";
137
138 if (loggedInUser.User.Username != (string)Session["ChatUsername"])
139 sb.Append(userIcon + "<a href=#>" + loggedInUser.User.Username + "</a><br>");
140 else
141 sb.Append(userIcon + "<b>" + loggedInUser.User.Username + "</b><br>");
142 }
143
144 // holds the names of the users shown in the chatroom
145 litUsers.Text = sb.ToString();
146 }
8.完成上叙代码,现在当你进入聊天室后,系统会把你进入聊天室的消息通知给该聊天室的当前用户。
接着,就是发送聊天信息:
58 ScriptManager1.SetFocus(txtMessage.ClientID);
68 ScriptManager1.SetFocus(txtMessage);
<form id="form1" defaultbutton="btnSend" defaultfocus="txtMessage" runat="server" >
<body style="background-color: gainsboro;" onload="SetScrollPosition()" onunload="LogMeOut()">
控制代码:
function SetScrollPosition()
{
var div = document.getElementById('divMessages');
div.scrollTop = 100000000000;
}
登出聊天室:
想退出聊天室,要么点退出按钮,要么直接关了浏览器,^_^
189 protected void BtnLogOut_Click(object sender, EventArgs e)
190 {
191 // log out the user by deleting from the LoggedInUser table
192 LinqChatDataContext db = new LinqChatDataContext();
193
194 var loggedInUser = (from l in db.LoggedInUsers
195 where l.UserID == Convert.ToInt32(Session["ChatUserID"])
196 && l.RoomID == Convert.ToInt32(lblRoomId.Text)
197 select l).SingleOrDefault();
198
199 db.LoggedInUsers.DeleteOnSubmit(loggedInUser);
200 db.SubmitChanges();
201
202 // insert a message that this user has logged out
203 this.InsertMessage("Just logged out! " + DateTime.Now.ToString());
204
205 // clean the session
206 Session.RemoveAll();
207 Session.Abandon();
208
209 // redirect the user to the login page
210 Response.Redirect("Default.aspx");
211 }
<body style="background-color: gainsboro;" onload="SetScrollPosition()" onunload="LogMeOut()">
JavaScript脚本:
function LogMeOut()
{
LogOutUserCallBack();
}
8 public partial class Chatroom : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
220 void System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
221 {
222 _callBackStatus = "failed";
223
224 // log out the user by deleting from the LoggedInUser table
225 LinqChatDataContext db = new LinqChatDataContext();
226
227 var loggedInUser = (from l in db.LoggedInUsers
228 where l.UserID == Convert.ToInt32(Session["ChatUserID"])
229 && l.RoomID == Convert.ToInt32(lblRoomId.Text)
230 select l).SingleOrDefault();
231
232 db.LoggedInUsers.DeleteOnSubmit(loggedInUser);
233 db.SubmitChanges();
234
235 // insert a message that this user has logged out
236 this.InsertMessage("Just logged out! " + DateTime.Now.ToString());
237
238 _callBackStatus = "success";
239 }
215 string System.Web.UI.ICallbackEventHandler.GetCallbackResult()
216 {
217 return _callBackStatus;
218 }
29 // create a call back reference so we can log-out user when user closes the browser
30 string callBackReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "LogOutUser", "");
31 string logOutUserCallBackScript = "function LogOutUserCallBack(arg, context) { " + callBackReference + "; }";
32 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "LogOutUserCallBack", logOutUserCallBackScript, true);
结语:
老外的文章还是不怎么好翻译,要保证翻译后的文章达到信,达,雅这个高度太难了。不过因为好玩把这篇文章坚持看完,收获还是不小。原文最后还有一些话没翻译,如果想看,点击本文开头就可以找到原文。我就偷下懒了~
代码下载: Click here to download the code