ASP.NET 和 Ajax 聊天






2.75/5 (8投票s)
一篇关于使用 ASP.NET 和 Ajax 开发聊天应用程序的文章
引言
本文介绍了如何使用 ASP.NET 和 Ajax 实现一个 Web 聊天。第一部分介绍了我为应用程序使用的技术。然后我解释了聊天概念,最后一部分我展示了主要的实现。本文的目的是向感兴趣的读者展示如何开发一个不带浏览器插件或 Java 小程序的聊天,仅使用纯 HTML 和 JavaScript。
使用了什么技术?
Web 聊天应用程序需要动态生成的 HTML 和客户端-服务器交互。因此,使用了 ASP.NET 2.0,当然还有 Ajax 用于客户端-服务器交互而无需回发。我们可以使用 Ajax.NET,但为了简单起见,我们决定使用 Mike Schwartz 的 Ajax 实现,称为 AjaxPro。
要从 JavaScript 使用 AjaxPro 进行所有服务器端调用,您需要执行以下操作:
- 添加对 Mike Schwartz 的程序集 AjaxPro.dll 的引用。
- 在您的项目中添加一个类。
- 在您希望通过脚本调用的类中添加一个方法,并使用 AjaxMethod 属性标记它。
- 在您希望使用它的 aspx 页面的 Page_Load 处理程序中注册该类。通过
AjaxPro.Utility.RegisterTypeForAjax(typeof(MyAjaxClass));
就这样。其他细节将在文章的实现部分进行解释。
聊天的设计?
有不同类型的聊天。在此示例中,我设计了一个用户可以使用用户名和密码登录的聊天。然后他们可以进入聊天并发送消息。消息对所有其他聊天用户可见。这是一个公共聊天,所有登录的聊天者都可以相互交流。

Session 包含一个 CurrentChatter
,即刚刚登录的用户。聊天者通过导航到聊天页面 (Chat.aspx) 进入聊天 (1)。聊天者进入后,他们可以通过在 TextBox 中键入文本并按 Enter 键来发送消息。然后,聊天消息被发送到一个 ChatMessageQueue
(CMQ),在本例中存储在 Application (2) 中。好的,现在消息在服务器上的 CMQ 中。我们必须从中获取它,以便每个客户端都能看到它。因此,我们有一个正在运行的 JavaScript 定时器,它从 CMQ 获取所有新消息并将其显示在 HTML 的 DIV 中,例如 (3)。听起来很简单,不是吗?以下是我们实现第 1 到 3 点需要做的事情:
(1) AddChatter (存储聊天用户)
成功登录后将当前用户保存到 Session。
(2) AddToMsgQueue
发送聊天消息时,需要将其存储在 CMQ 中。您必须从 JavaScript 函数调用此操作。脚本代码通过 Ajax 调用服务器端方法,该方法可以访问 ASP.NET 应用程序。
(3) GetMsgsFromQueue
在这里,我们需要每 n 秒在 JavaScript 定时器中检查是否有新聊天消息可供客户端显示。因此,我们通过 Ajax 方法轮询 CMQ 以获取新消息。如果我们有新消息,这些消息将被转换为可以显示为聊天窗口中列表的字符串。
实现
到目前为止是理论,现在是具体的编码。以下是我们需要的 datatypes:
Chatter
此类具有一个 Id 来内部标识聊天者,以及一个用于显示的名称。LastMsgKey
是聊天者收到的最后一条消息的键。当定时器轮询新消息时,此键用于确定在该消息之后 CMQ 中是否有消息。消息存储在应用程序的列表中。如果列表中有该聊天者在 LastMsgKey
之后的消息,则必须获取这些消息。
ChatMsg
聊天消息有一个 Key (Guid)、发送该消息的聊天者的姓名以及消息本身(字符串)。
ChatMgr
ChatMgr
处理所有登录聊天者的列表和 CMQ。您可以向 CMQ 添加消息并从中检索它们。它还具有获取所有可用聊天者列表(HTML 格式)的方法。代码可以在此处优化:聊天者和聊天消息的显示逻辑可以放在另一个类中。
HTML 组件位于 WebForm Chat.aspx 上。我们有:
- divChatBox:用于所有聊天消息的 DIV。
- divChatters:用于所有登录聊天者的 DIV。
- txtMessage:用于聊天者可以输入和发送的文本的 TextArea。
页面加载时,所有登录的聊天者和可用的消息将被加载并显示在相应的 HTML 元素中。这是调用的 JavaScript 代码,因为我们将调用添加到 Chat.aspx 页面的 onload 处理程序中。
function fillUsers()
{
ChatMgr.GetChattersHtml( fillUsers_CallBack );
}
function fillUsers_CallBack( res )
{
var userBox = document.getElementById('divUsers');
if( res.value == '' )
{
setTimeout( "fillUsers()", 5000 );
return;
}
userBox.innerHTML = res.value;
setTimeout( "fillUsers()", 5000 );
}
function getMsgs()
{
ChatMgr.GetMsgsFromQueue( getMsgs_CallBack );
}
function getMsgs_CallBack( res )
{
var chatBox = document.getElementById('divChatBox');
chatBox.innerHTML += res.value;
scrollContentDown();
setTimeout( "getMsgs()", 2000 );
}
_callback
函数是异步回调。它们由 ChatMgr
的 Ajax 调用启动。在 _callback
函数的末尾调用 setTimeout
以在一定时间后再次调用该函数。现在 ChatMgr
如何能够从脚本调用服务器端函数?请参阅调用 GetChattersHtml
的示例。
[ AjaxMethod( HttpSessionStateRequirement.Read ) ]
public string GetChattersHtml()
{
string result = "";
if( SessionMgr.Instance.OnlineUsers == null )
return result;
foreach (Member member in SessionMgr.Instance.OnlineUsers.Values )
{
result += "<div class='ChatUser' style='width: 280px'>";
result += "<table border=0 cellpadding=0 cellspacing=0><tr>";
result += "<td>" + UserImage.GetHtml( member.ID, "" ) + "</td>";
result += "<td> <b>" + member.Name + "</b></td>";
result += "</tr></table>";
result += "</div>";
}
return result;
}
ChatMgr
的方法用 AjaxMethod
属性标记。要访问当前 Session,我们向该属性添加 HttpSessionStateRequirement.Read
。现在该方法可以从 Session 中读取所有登录的用户,并以 HTML 格式返回列表。如果我们还希望能够写入 HttpSession,我们可以使用 HttpSessionStateRequirement.ReadWrite
。
对于其他代码部分,情况相同:脚本调用服务器端方法,该方法返回返回值,这些返回值在脚本的异步回调函数中被读取。
这是将消息发送到队列的逻辑:
function sendMessage()
{
var newMsg = '';
var chatBox = null;
var msg = document.getElementById('txtMsg').value;
if( msg == '' )
return;
document.getElementById('txtMsg').value = '';
newMsg = ChatMgr.AddToMsgQueue( msg ).value;
chatBox = document.getElementById('divChatBox');
chatBox.innerHTML += '' +
newMsg.Name + ': ' + newMsg.Message + '';
}
按 Enter 键时,将调用 sendMessage
函数,并通过调用 ChatMgr
的 AddToMsgQueue
方法将消息添加到 CMQ,该方法也是一个 Ajax 方法。如果您对如何构建 ASP.NET-Ajax 聊天有任何疑问,或者希望 codegod 为您实现,请随时发送电子邮件给我们。
您可以在 这里 看到 codegod 聊天实际运行效果(登录后)。有关 ASP.NET 和 Ajax 的更多信息,请访问我们的 页面。