COMET: ASP.NET 网络应用程序的多客户端连续更新网格第 2部分

分享于 

17分钟阅读

Web开发

  繁體

注意:你的反馈对我很重要。 如果你觉得这篇文章有用的话,请在下面留言,然后投票。

介绍

大自然是如此神奇,几乎没有两个实体是相同的;每个实体都是唯一的。 没有两个人是相同的;每一个人都是独一无二的。 同样,业务需求也不相同,但它们是唯一的。 这就需要为每个业务设计定制的软件系统,即使它们在同一行业,也就是财务或者医疗。 换句话说,同一套软件相同,不能满足同一区域的两个财务公司。 他们的方法不同,需求不同,设计不同。 这使得其中一个比另一个更成功。

在本文介绍了COMET网格控制 ( 单击链接) 插件之后,本文将重点介绍如何在该领域中进一步使用一个专门的。 在前一篇文章中,我们讨论了一个广义。 在本文中,我们将讨论使用COMET方法更新不同数据的多个客户机。 也就是说,我们有一个显示天气信息的ASP.NET 页面。 ,位于芝加哥的一位web客户机位于芝加哥,它的位于芝加哥。 显然,我们需要将不同的天气数据发布到Alice和 Bob。 以前的文章网格控件只具备更新相同数据的所有客户机的能力。 这对我们的要求是不合适的。 我们需要用不同的数据更新Alice和 Bob。 本文介绍了具有该功能的网格控件: 一个多客户端更新网格控件。 一如既往,可以下载完全工作的示例。

更专业的例子:考虑一个金融公司拥有很多交易。 每个交易台集中于在特定地区执行交易。 Bob是一个名为'组合 1'的投资组合的商人。 Alice恰好管理 15个这样的投资组合,比如投资组合 1到 15. 考虑到他们需要一个 ASP.NET web应用程序来跟踪他们的p/l ( 损益/损失),当它发生时。 如上所述,前一篇文章中提到的COMET网格将在这里提供我们的需求。 这是因为Alice需要 15 portfolio(s),的总p/l ( 损益/损失),而Bob只是关心他负责的'组合 1'。 因此,我们需要一个能够向不同客户机发布不同数据的COMET网格。 这个业务案例可以在几个小时内完成,使用这个多客户机COMET网格。 这里案例的示例也可以下载。

示例:ASP.NET 网络应用中的COMET多客户端网格

以下示例为 application/l 示例页面的示例p/l 贸易展示。 请注意,Alice获得 *total* (。产品组合 1至 15 ) p/l 更新,而Bob只获取p/l portfolio_1更新。 另外,请注意Bob的地址栏和alice的浏览器。 它们都引用相同的地址( 同样的网格控制),但是( 使用 COMET ) 中的数据是不同的。

bob窗口的浏览器:

BobView.gif

alice窗口浏览器:

AliceView.gif

以下示例显示了应用程序页面的样例天气显示。 请注意,Alice得到的更新与Bob不同。 但是,代码只使用一个COMET网格控件来更新Alice和 Bob。

alice窗口浏览器:

AliceWeather.gif

bob窗口的浏览器:

BobWeather.gif

你希望如何阅读?

最好按顺序阅读文章。 然而,并非每个人都处于相同的状态。 下面是获取你要快速查找的内容的简短指南:

  • 如果你快速抓取要在项目中使用的控件,那么你只需阅读一下'使用代码'节即可以。
  • 如果你对设计感到好奇,请阅读'COMET多客户端网格设计的解释'部分。
  • 如果希望阅读这里项目中使用的数据结构,请阅读这里的MultiMap MultiMap泛型集合
  • 参考文献部分建议进一步阅读本主题。

使用代码

先决条件: Visual Studio 2008.

快速演示: 从顶部的链接下载示例项目。 在VS2008中运行它。复制地址栏中的链接。 打开另一个浏览器实例。粘贴地址栏中的链接。 现在你可以在Browser_1实例和Browser_2实例中看到alice信息的天气。

使用这个基于COMET的网格控件在三个简单步骤中使用了 :

  • 将这里控件添加到项目中:
  • 右键单击工具箱| 选择'选择项目。'| 单击浏览。 然后,浏览以选择下载的(。从本文的第一行开始) 程序集( GridControlCometAjax.dll )。
  • 从工具箱中,将新添加的控件拖放到网页中。
  • 在 web.config 文件中将一个异步处理程序添加到下面的节'httpHandlers'中:
<addverb="GET, POST"path="GridControlCometAjax.ashx"type="BK.Util.GridAsynchHandler, GridControlCometAjax"validate="false">
  • 在( 比如说 Default.aspx.cs ) 后面的代码中,在'Page_Load'方法中添加下面的行。 记住,你需要在使用 Dyn 方法( 下面解释了) 进行客户端更新调用之前调用方法 LoadControl
protectedvoid Page_Load(object sender, EventArgs e)
{
 // Your code goes here.// Assuming the control instance's name// is GridControlCometAjax1, add the below line: GridMultiClientControlComet1.LoadControl(this);
}

好了就这样开始使用控制。 使用前缀'动态'的任何方法更新这里网格控件中的任何内容将自动传播到客户端。 此外,这些方法是线程安全的。 所以你可以从多个线程调用这些方法。

用例 1: 如何声明和添加这里多客户机COMET网格控件的元素。

using System;using BK.Util;namespace WeatherWatch 
{
 publicpartialclass _Default 
 {
 // Other declarations can go hereprotectedglobal::BK.Util.GridMultiClientControlComet 
 GridMultiClientControlComet1; 
 // Other declarations go here. }
}

文件 default.aspx.cs:

using System;using BK.Util;namespace WeatherWatch
{
 publicpartialclass _Default : System.Web.UI.Page
 { 
 protectedvoid Page_Load(object sender, EventArgs e)
 {
 GridMultiClientControlComet1.LoadControl(this);
 // Error checks are avoided for brevityint rowCount, colCount;
 // Get the Number of rows available to update GridMultiClientControlComet1.DynGetRowCount(
 this.Session.SessionID, ref rowCount);
 // Get the number of Columns available to update GridMultiClientControlComet1.DynGetColCount(
 this.Session.SessionID, ref colCount);
 // Modify values of each Row element to value RowItem*ColItem;for (int RowItem = 0; RowItem < rowCount; RowItem++)
 {
 for (int ColItem = 0; ColItem < colCount; ColItem++)
 {
 int Update = RowItem * ColItem;
 GridMultiClientControlComet1.DynModifyTableItem(this.Session.SessionID, 
 RowItem, ColItem, Update.ToString(), false);
 }
 }
 }
 }
}

在上面的代码中,第一行加载控制 [as stated in step (3)]。 接下来的行循环来填充元素。

用例 2: 如何更新这里COMET网格控件的背景颜色。

代码说明可以内联提供:

// Parameter 1 is Session Id// Parameter 2 is Row // Parameter 3 is Column// Parameter 4 is Color to update// Parameter 5 states if the update need to be propogated to the client or not.GridMultiClientControlComet1.DynModifyTableFColor(SessionID, 0, 0, 
 System.Drawing.Color.LightBlue, false);

用例 3: 如何更新这里COMET网格控件的前景或者文本颜色。

代码说明可以内联提供:

// Parameter 1 is Session Id// Parameter 2 is Row // Parameter 3 is Column// Parameter 4 is Color to update// Parameter 5 states if the update need to be propogated to the client or not.GridMultiClientControlComet1.DynModifyTableFColor(session1, 0, 0, 
 System.Drawing.Color.DarkBlue, false);

如何动态调整背景图像的大小。

代码说明可以内联提供:

// Parameter 1 is Session Id// Parameter 2 is Row // Parameter 3 is Column// Parameter 4 is ralative Image path to update// Parameter 5 states if the update need to be propogated to the client or not.GridMultiClientControlComet1.DynModifyBackImage(session1, 0, 0, "Img2/Rain.gif", false);

你会注意到,与前面的(。文章COMET的常规) 控件相比,使用这里COMET网格控件的唯一区别是 SessionID 参数。 这个参数告诉网格要将更新发送到哪个客户端。 所有其他客户端都将从更新中排除。

性能结果

我利用微软应用压力测试工具Web进行压力测试。 一个完整的报告作为可以下载的文件附加在上面的链接中。 不过,下面给出了概述。 我在每个线程中使用 100个线程,每个线程使用 10套接字,这意味着 1000并发连接。 我使用的测试应用程序使用两个网格控件更新客户机。 以下是结果:

Performance.jpg

COMET多客户端网格设计的解释

如果你正计划使用这个COMET网格控件,你可以跳过这个部分。 但是,如果你很好奇,请继续阅读。

简而言之,在下面的图片中,当客户端连接时,调用将保持挂起状态。 当需要从服务器端更新数据时,保持挂起的客户端的特定调用将被占用。 通过填写需要更新的数据完成这里调用。 其他客户端未更新,并且它们的呼叫保持挂起状态。

另外,在预先确定的时间间隔内对所有客户端执行维护更新,以便所有连接的客户端由于浏览器超时而不会中断连接。

要详细解释:

  • 步骤 1: 客户端对服务器进行调用。
  • 步骤 2: 服务器返回带有包含控件的ASP.NET 页面的调用,包括这个COMET网格。
  • 步骤 3: COMET网格对服务器进行AJAX样式调用以获得更新。
  • 步骤 4: 调用不是由服务器完成的,而是保持挂起状态。
  • 步骤 5: 服务器等待任何服务器端事件,如对任何客户机或者超时的数据更新。
  • 步骤 6: 如果在服务器端发生事件,则会发送客户端更新。 其他客户端调用仍保持挂起状态。
  • 步骤 7: 如果发生超时,所有客户端调用都将完成。
  • 步骤 8: 从步骤( 3 ) 继续。

让我们看看上面这些步骤中有趣的部分。 最有趣的部分是保持客户端挂起的调用。 这是通过编写基于 IHttpAsyncHandler的处理程序实现的。 我们所需要做的就是重写三种方法: BeginProcessRequestEndProcessRequestProcessRequest。 我们在 ProcessRequest 中没有做任何事情。 在 BeginProcessRequest 中,我们所做的就是: 将呼叫置于挂起状态。 因为这将把 ASP.NET 线程返回给线程池,从而释放服务器的资源,这是一个重要步骤。 因此,同样的线程可以用于服务任何进一步连接客户端。 代码如下所示:

public IAsyncResult BeginProcessRequest(HttpContext Context, 
 AsyncCallback Callback, object ExtraData)
{
 string ClientId = Context.ApplicationInstance.Request.QueryString[0]; //Line 1string SessionId = Context.ApplicationInstance.Request.QueryString[1]; // Line 2 ResponseDetails respDet = clientDetails.GetFirstItem(ClientId); // Line 3 GridAsynchResult asyncResultToAdd = new GridAsynchResult(SessionId, respDet, 
 Context, Callback, ClientStatus.Updated); // Line 4 respDet.AddClient(asyncResultToAdd); // Line 5return asyncResultToAdd; // Line 6}

在上面的代码中,第一行获取 clientId。 这是网格控件的ID。 如果有两个网格控件,将有两个不同的clientId 来表示它们。 第二行接受会话 ID,一个区分每个客户端的字符串。 第 3行检索已经为该客户端存储的响应详细信息。 响应详细信息类存储连接的客户机队列和控件的网格实例。 这里信息被添加到新创建的AsynchResult实例。 将AsynchResult返回给调用方。 如上所述,这里方法释放 ASP.NET 线程,这使得更多的客户端可以同时连接。

当需要在网格中发生数据更改的服务器端事件时,asynchresult方法的SetCompleted 将被调用。 请注意,服务器端事件由这里控件的用户触发。 如果使用这里控件,则 换句话说,将调用 GridInstanceName.DynUpdateClient() 方法触发这里服务器端事件。 为了进行调用,在AsynchResult上调用 SetCompleted 方法。 这导致调用 EndProcessRequest。 此外,我们在这里方法中所做的全部工作是将XML响应写入客户端( 这使得AJAX风格的调用)。 这就完成了对客户端的调用。 EndProcessRequest的代码如下所示:

publicvoid EndProcessRequest(IAsyncResult result)
{
 GridAsynchResult asynchResult = (GridAsynchResult)result; // Line 1 asynchResult.ClientContext.Response.ContentType = "text/xml"; // Line 2 asynchResult.ClientContext.Response.Write(
 asynchResult.RespDetails.GridCtrlAjaxInstance.GetXmlFeed(
 asynchResult.SessionId)); // Line 3}

第 1行获取传递的参数。 响应类型在第 2行标记为'xml'。 第 3行获取XML响应并写入 Response 对象。 第 4行完成来自客户端的调用。

Points of interest

  • 这个多客户机COMET控件能够在保存资源的同时更新特定客户机。 这里控件避免了来自多个客户端的计时器的几个不必要的AJAX调用。
  • 线程安全:这个多客户机网格是线程安全的。 你可以从多个线程调用'动态'前缀的方法。 换句话说,它的中一个线程可以能更新值,另一个可以能调用 DynUpdateClient 来向特定客户端发送更新。
  • 控件不仅支持动态更新特定( 客户端浏览器站点'网格数据,还支持动态改变背景颜色。文本颜色和背景图像。

重要提醒 !

我想从你们的反馈中得到消息。 我希望听到你的详细反馈,即使你投票 1. 所以请写下你的留言。 谢谢!

引用

历史记录

  • 3 2009年04月 - 第一个版本。

COM  WEB  PAR  asp  asp-net  GRID  
相关文章