在SignalR和ASP.NET MVC4之间同步客户端状态(或者我应该使用SignalR?)



背景:

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

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

当前部分解决方案:

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

问题:

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

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

我为您制作了一个库,它是一个围绕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

对于问题1,客户端发送启动任务的请求,MVC处理该请求,并应发送包含taskId的响应。从新网页,SignalR连接启动,您应该定义一个Hub方法,如Register(taskId),并在服务器上将taskId映射到Context.ConnectionId–Gustavo Armenta Aug 29 at 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

最新更新