16

如何使用 SignalR 在 .NET 4.0 系统中实现通知,该系统由 ASP.NET MVC 3 应用程序(使用表单身份验证)、SQL Server 2008 数据库和 MSMQ WCF 服务(托管在 WAS 中)来处理数据?运行时环境由在 Windows Server 2008 R2 标准版上运行的 IIS 7.5 组成。

我只玩过样本,对 SignalR 没有广泛的了解。

这是一些背景

Web 应用程序接受来自用户的数据并将其添加到表中。然后它调用 WCF 服务的单向操作(使用数据库键)来处理数据(任务)。Web 应用程序返回到一个页面,告诉用户数据已提交,处理完成后将通知他们。用户可以查看“索引”页面以查看哪些任务已完成、失败或正在进行中。他们可以继续提交更多的任务(这与之前的数据无关)。他们可以关闭浏览器,稍后再回来。

基于 MSMQ 的 WCF 服务从数据库中读取记录并处理数据。这可能需要几毫秒到几分钟的时间。处理完数据后,记录会更新相应的状态(错误或失败)和结果。

大多数时候,WCF 服务不执行任何处理,但是当它执行时,用户通常希望尽快知道它何时完成。用户仍将使用 Web 应用程序的其他部分,即使他们没有要由 WCF 服务处理的数据。

这就是我所做的

在主导航栏中,我有一个指示器(类似于 Facebook 或 Google+)供用户在任务状态发生变化时通知他们。当他们单击它时,他们会获得所做工作的摘要,然后可以根据需要查看结果。

使用 jQuery,我轮询服务器以获取更改。控制器操作检查是否有任何进程被修改(完成或失败)并返回它们,否则等待几秒钟并再次检查而不返回客户端。为了避免客户端超时,如果没有更改,它将在 30 秒后返回。jQuery 脚本等待一段时间并再次尝试。

问题

每个查看页面的用户都会降低性能。他们不需要做任何特别的事情。我们注意到 Firefox 7+ 和 Safari 的内存使用量随着时间的推移而增加。

使用 SignalR

我希望切换到 SignalR 可以减少轮询,从而减少资源需求,特别是如果数据库中的任务方面没有任何改变。鉴于它使用基于表单的身份验证,我无法让 WCF 服务通知客户端它已完成处理任务。

通过提出这个问题,我希望有人能让我更好地了解他们将如何使用 SignalR 重新设计我的通知方案(如果有的话)。

4

1 回答 1

8

如果我理解正确,您需要一种将任务与给定用户/客户相关联的方法,以便您可以在他们的任务完成时告诉客户。

SignalR API 文档告诉我,您可以根据客户端 ID ( https://github.com/SignalR/SignalR/wiki/SignalR-Client ) 为特定客户端调用 JS 方法。从理论上讲,您可以执行以下操作:

  1. 将 SignalR 使用的客户端 ID 存储为任务元数据的一部分:
  2. 正常排队任务。
  3. 当任务被处理和出队时:
    • 使用状态更新您的数据库。
    • 使用作为该任务的一部分存储的客户端 ID,使用 SignalR 向该客户端发送通知:

您应该能够检索客户端正在使用的连接并向他们发送消息:

string clientId = processedMessage.ClientId //Stored when you originally queued it.
IConnection connection = Connection.GetConnection<ProcessNotificationsConnection>();
connection.Send(clientId, "Your data was processed");

这假设您映射了此连接,并且客户端首先使用该连接来启动数据处理请求。您的“主导航栏”具有启动与ProcessNotificationsConnection您之前映射的端点的连接的 JS。

编辑:来自https://github.com/SignalR/SignalR/wiki/Hubs

public class MyHub : Hub
{
     public void Send(string data)
     {
     // Invoke a method on the calling client
     Caller.addMessage(data);

     // Similar to above, the more verbose way
     Clients[Context.ClientId].addMessage(data);

     // Invoke addMessage on all clients in group foo
     Clients["foo"].addMessage(data);
     }
}
于 2011-11-21T15:56:42.437 回答