0

背景:

这是我的项目:在 ASP.NET MVC4 Web 应用程序上,用户输入信息并发布到服务器。然后服务器开始运行一个长任务(从不到一秒到 20 分钟不等。通常大约 4 分钟。)

我不希望所有工作都发生在 Controller 操作中,否则用户将不得不等待它完成而没有关于正在发生的事情的反馈。所以我想将用户发送到状态页面并将服务器的更新发送到该页面。

当前部分解决方案:

到目前为止,这是我所拥有的:控制器使用长时间运行的操作启动一个任务,然后将用户引导到状态页面。当任务运行时,它会使用 SignalR 将消息发送回状态页面,并且页面会更新。

问题:

  1. SingalR 正在更新所有客户端,因此多个用户不能同时使用此应用程序。我看到 SignalR 可以向特定客户端发送消息,但是如何将客户端 ID 获取到控制器?SignalR 使访问会话变得困难(不可能?)。
  2. 如果任务在状态页面加载之前完成怎么办(或者如果在页面加载时更新之间存在暂停怎么办?)状态页面将没有关于任务的任何信息。同样,将状态存储在会话中会很好,但我似乎无法做到这一点。

有没有办法让 SignalR 和 ASP.NET 同步客户端状态?SignalR 是适合这项工作的工具吗?

4

2 回答 2

2

我已经为你所需要的做了一个库,它是一个围绕 SignalR 的包装库。它要求您拥有某种消息总线/事件聚合器。然后,我的库在您的消息总线和 SignalR 客户端之间代理。

这样,您的后台工作人员可以轻松地将进度报告发送到后端的其他组件和无缝的客户端。

使用 nuget 安装

Install-Package SignalR.EventAggregatorProxy

您需要实现一个服务总线/事件聚合器。Caliburn Micro 占地面积小

Install-Package Caliburn.Micro.EventAggregator

按照 wiki 如何设置

https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki

完成设置后,您可以从 javascript 收听此类事件

ViewModel = function() {
   signalR.eventAggregator.subscribe(MyApp.Events.BackgroundWorkerProgressEvent, this.onProgressEvent, this);
};

忘了说这里有一个Demo项目 https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/tree/master/SignalR.EventAggregatorProxy.Demo.MVC4

于 2013-08-29T19:37:54.707 回答
1

对于问题 1,客户端发送启动任务的请求,MVC 处理请求并应发送包含 taskId 的响应。从新网页开始,SignalR 连接启动,您应该定义一个 Hub 方法,如 Register(taskId),并在服务器上将 taskId 映射到 Context.ConnectionId – Gustavo Armenta 8 月 29 日 19:04

@GustavoArmenta 好的,所以服务器将任务的某种 ID 发送回客户端,然后客户端通过 SignalR 连接并注册其 TaskID,然后将其映射到客户端 ID。然后正在运行的任务使用该映射来发回信息,对吗?但是任务如何访问任务 ID 到客户端 ID 的映射呢?控制器如何访问 SignalR 集线器中的持久数据?– Danation 8 月 29 日 19:15

好吧,您可以使用静态字典将映射保存在内存中,或者将数据保存到数据库中 – Gustavo Armenta 8 月 30 日 16:47

@GustavoArmenta,我最终选择了您的选择(我能够解决这两个问题。)如果您将其添加为答案,我会接受。– Danation 9 月 18 日 4:17

于 2013-09-24T22:05:13.117 回答