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

C# 在SignalR和ASP.NET MVC4之间同步客户端状态(或者我应该使用SignalR吗?),c#,asp.net-mvc,asp.net-mvc-4,signalr,signalr.client,C#,Asp.net Mvc,Asp.net Mvc 4,Signalr,Signalr.client,背景: 这是我的项目:在ASP.NET MVC4 web应用程序上,用户输入信息并发布到服务器。然后服务器开始运行一个长任务(从不到一秒到20分钟不等,通常大约4分钟) 我不希望所有的工作都发生在控制器操作中,否则用户将不得不等待它完成,而没有关于正在发生什么的反馈。因此,我希望将用户发送到状态页面,并将更新从服务器发送到该页面 当前部分解决方案: 到目前为止,我已经知道了:控制器使用长时间运行的操作启动一个任务,然后将用户引导到状态页面。当任务运行时,它使用SignalR将消息发送回状态页面,

背景:

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

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

当前部分解决方案:

到目前为止,我已经知道了:控制器使用长时间运行的操作启动一个任务,然后将用户引导到状态页面。当任务运行时,它使用SignalR将消息发送回状态页面,页面将更新

问题:

  • SingalR正在更新所有客户端,因此多个用户不能同时使用此应用。我看到signer有一种向特定客户机发送消息的方法,但是如何将客户机ID发送给控制器呢?SignalR使访问会话变得困难(不可能?)
  • 如果任务在状态页面加载之前完成(或者在页面加载时更新之间出现暂停),状态页面将不包含任何有关任务的信息。同样,在会话中存储状态也很好,但我似乎无法做到这一点

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

    我为您所需要的东西制作了一个库,它是signer的包装库。它要求您具有某种消息总线/事件聚合器。然后,我的库在消息总线和信号器客户端之间进行代理

    通过这种方式,您的后台工作人员可以轻松地向后端的其他组件和客户端发送进度报告

    使用nuget安装

    Install-Package SignalR.EventAggregatorProxy
    
    您需要实现一个服务总线/事件聚合器。Caliburn Micro的脚印很轻

    Install-Package Caliburn.Micro.EventAggregator
    
    按照wiki的说明进行设置

    一旦您完成了设置,您就可以从javascript收听类似这样的事件

    ViewModel = function() {
       signalR.eventAggregator.subscribe(MyApp.Events.BackgroundWorkerProgressEvent, this.onProgressEvent, this);
    };
    
    忘了提到这里有一个演示项目

    我已经为您所需要的东西创建了一个库,它是一个围绕Signal的包装器库。它要求您具有某种消息总线/事件聚合器。然后,我的库在消息总线和信号器客户端之间进行代理

    通过这种方式,您的后台工作人员可以轻松地向后端的其他组件和客户端发送进度报告

    使用nuget安装

    Install-Package SignalR.EventAggregatorProxy
    
    您需要实现一个服务总线/事件聚合器。Caliburn Micro的脚印很轻

    Install-Package Caliburn.Micro.EventAggregator
    
    按照wiki的说明进行设置

    一旦您完成了设置,您就可以从javascript收听类似这样的事件

    ViewModel = function() {
       signalR.eventAggregator.subscribe(MyApp.Events.BackgroundWorkerProgressEvent, this.onProgressEvent, this);
    };
    
    忘了提到这里有一个演示项目

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


    @Gustavarmenta好的,那么服务器向客户端发送任务的某种方式的ID,然后客户端通过信号器连接并注册其TaskID,然后将其映射到客户端ID。然后运行的任务使用该映射发送回信息,对吗?但是任务如何访问任务ID到客户端ID的映射呢?控制器如何访问信号集线器中的持久数据丹麦8月29日19:15


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


    @GustavoArmenta,我最终选择了你的选项(我能够解决这两个问题)。如果你把它作为一个答案,我会接受的日期9月18日4:17对于问题1,客户端发送启动任务的请求,MVC处理该请求并应发送包含taskId的响应。在新网页中,信号器连接启动,您应该定义一个集线器方法,如Register(taskId),并在服务器上将taskId映射到Context.ConnectionId–Gustavo Armenta 8月29日19:04


    @Gustavarmenta好的,那么服务器向客户端发送任务的某种方式的ID,然后客户端通过信号器连接并注册其TaskID,然后将其映射到客户端ID。然后运行的任务使用该映射发送回信息,对吗?但是任务如何访问任务ID到客户端ID的映射呢?控制器如何访问信号集线器中的持久数据丹麦8月29日19:15


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


    @GustavoArmenta,我最终选择了你的选项(我能够解决这两个问题)。如果你把它作为一个答案,我会接受的日期9月18日4:17

    问题2可以通过消息总线解决。对于问题1,客户端发送启动任务的请求,MVC处理该请求,并应发送包含taskId的响应。在新网页中,启动信号器连接,您应该定义一个中心方法,如Register(taskId),并在服务器上将taskId映射到上下文。ConnectionId@Romoku我不知道那是什么。您能提供更多详细信息吗?@gustavarmenta好的,因此服务器会将任务的某种形式的ID发送回客户端,然后客户端通过signar连接并注册其TaskID,然后将其映射到客户端ID。然后运行的任务使用该映射发送回信息,对吗?但是任务如何访问任务ID到客户端ID的映射呢?控制器如何访问信号集线器中的持久数据,