我相信大多数读者都使用或了解过MSN Messenger。当某个人刚上线时,一个弹出窗口会友好地出现在屏幕的右下角,通知你—你的朋友某某刚上线。这是一种非常友好的设计。另外,使用过网易在线邮箱的朋友也都会熟悉在新邮件到来时在浏览器窗口的右下角弹出的友好的自动报警小窗口,这实在是一种极具人性化的设计。
那么,在ASP.NET页面开发环境中,能否也可以实现类似的效果呢?答案是肯定的。
在本文中,让我们来共同探讨如何实现这样的一个类似于MSN的消息通知窗。无论何时有一条新的记录添加到数据库表格(模拟新的邮件发送到你的邮箱中)中,一个弹出窗将显示于ASP.NET页面的右下角以通知你有一条新记录被添加进去。
另外,我们将使用ASP.NET 2.0 AJAX 1.0 Extensions部分(即框架的最基本部分,它已经被集成进微软Visual Studio 2008中的ASP.NET 3.5中)并主要通过客户端AJAX编程调用本地Web服务技术来实现本文中的示例程序。
<!--[if !supportLists]-->二、数据库设计
在本文示例中,我们使用了一个名为的数据库表格MyInbox来模拟你的位于一个邮件服务器上面的邮箱。这个表格包含了共三个字段:EmailFrom,Body和Date。这些字段用于模拟我们在收件箱中的电子邮件相应信息。
<!--[if !supportLists]-->三、<!--[endif]-->JavaScript编程
我们将创建一个新的支持AJAX功能的网站。然后,在HTML源码编辑状态下打开页面Default.aspx。在这里,我们将开始JavaScript编程以便实现显示/隐藏弹出窗口,并查看数据库以确定是否存在新插入的电子邮件。
首先,我们定义一个全局变量:
var numberOfEmails_original= 0;
这个numberOfEmails_original变量将存储页面初始加载时当前的数据库表格中的电子邮件总数。在后面,我们将看到何时及如何使用这个变量。接下来,我们添加一个相应于Application对象的Init方法的事件处理器。
var app = Sys.Application;
app.add_init(applicationInitHandler);
function applicationInitHandler(sender, args)
{
InboxService.GetLatestNumberOfEmails(OnCurrentNumberOfEmailsReady);
}
在此初始化过程中,我们调用了一个脚本服务来执行位于后面我们将讨论的AJAX服务中的GetLatestNumberOFEmails方法。我们指定当从服务器端发送回一个响应时运行一个success回调函数。
这里的思想是,在页面初始加载时,我们从服务器端取得当前电子邮件总数,并把它存储在变量numberOfEmails_original中。具体请参考如下的回叫函数OnCurrentNumberOfEmailReady:
function OnCurrentNumberOfEmailsReady(result, userContext, methodName)
{
numberOfEmails_original= result;
//开始检查
StartChecking();
}
在此,我们把从AJAX服务返回的结果存储于局部变量numberOfEmails_original中,然后调用方法StartChecking()。
现在,既然我们已经知道了存储于数据库的电子邮件总数,那么,接下来,从现在开始我们就可以开始检查任何添加到数据库表格中的新的电子邮件了。
这个StartChecking方法的代码如下所示:
function StartChecking(){
InboxService.GetLatestNumberOfEmails(OnLastestNumberOfEmailsReady);
}
这个StartChecking函数所做的唯一一件事情就是调用相同的AJAX服务方法—InboxService.GetLastestNumberOfEmails。但是,这次我们传递的是另一个success回调函数OnLatestNumberOfEmailsReady。其代码如下所示:
function OnLastestNumberOfEmailsReady(result, userContext, methodName)
{
var numberOfEmails_new = result;
if (numberOfEmails_new > numberOfEmails_original)
{
ShowPopup();
$get("modalBody").innerHTML = numberOfEmails_new - numberOfEmails_original;
//更新计数
numberOfEmails_original = numberOfEmails_new;
}
//再次开始检查
window.setTimeout(StartChecking, 10000);
}
在这个方法中,首先把
接下来,检查是否当前存储在数据库中的电子邮件总数大于页面最初从数据库中请求的数目。这意味着,自从上次查询数据库以来我们所拥有的新邮件被插入到数据库中。
如果这是真实的,那么将调用函数ShowPopup()—此函数负责以类似于MSN Messenger方式显示一个弹出窗口。然后,新邮件数显示于弹出窗口中以通知用户关于新收到的邮件总数;最后,我们把数据库表格中的当前的邮件数目设置为numberOfEmails_original变量的值。通过这种方式,numberOfEmails_original变量能够与数据库的电子邮件总数保持同步。对于后面要进行的客户端不断地检查操作来说刷新这个变量的值是很重要的。
此方法中的最后一句是调用StartChecking方法(位于一个window.setTimeout函数调用的内部)。因此,只要页面一直在运行中,检查将继续下去并且每当有一封新电子邮件添加到数据库表格中,将在屏幕上显示一个弹出窗口以通知用户新邮件已经添加。
下图1展示了页面初始加载时的情形。
图1—初始加载时的网页
当有一条新记录被插入到数据库时,你会注意到一个小的消息提示窗口恰好显示于整个窗口的右下角位置,见下图2。
图2—有新消息时出现一个类似MSN的弹出窗
最后两个函数ShowPopup和HidePopup作为普通的帮助函数用于显示和隐藏页面上的弹出窗口,篇幅所限,在此不多及,请参考源码。
<!--[if !supportLists]-->四、<!--[endif]-->构建AJAX服务
最后,我们来构建一个简单的AJAX服务,客户端将使用它来访问服务器端数据库并且检索存储在数据库中的记录总数。
[ScriptService]
public class InboxService: System.Web.Services.WebService
{
[WebMethod]
public int GetLatestNumberOfEmails()
{
int numberOfEmails = 0;
using(SqlConnection conn = new SqlConnection
(WebConfigurationManager.ConnectionStrings[0].ConnectionString))
{
using(SqlCommand cmd = new SqlCommand("GetLatestNumberOfEmails", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
numberOfEmails = (int)cmd.ExecuteScalar();
}
}
return numberOfEmails;
}
}
注意,位于服务顶部的ScriptService属性是非常重要的,因为只有这样才会使你的Web服务为客户端JavaScript脚本所调用。上面的Web服务包括了一个Web方法GetLatestNumberOfEmails,这个方法负责访问数据库和检索数据库中的记录或电子邮件总数。
<!--[if !supportLists]-->五、<!--[endif]-->结论
在本文中,我向你展示了如何创建一个类似于的弹出窗口,这个窗口在数据库中新添加一条记录时将弹出到网页的右下角。读者可以顺着这个思路继续下去。但是大致原理应该是一样的,即是当服务器端发生某个特定事件时将有一个弹出窗口跳进当前ASP.NET页面。
【注意】第一,本文源码调试环境为:Visual Studio 2008+SQL Server 2005。第二,为了实现本文展示的新邮件报警效果,你可以在示例网页运行后,切换到VS2008或SQL Server 2005的数据库表格MyInbox并往其中添加记录。此时,作为前台的浏览器端每隔1分钟将在浏览器窗口的右下角弹出小窗口报警新邮件的到来。