【问题标题】:Synchronizing client state between SignalR and ASP.NET MVC4 (or should I even use SignalR?)在 SignalR 和 ASP.NET MVC4 之间同步客户端状态(或者我什至应该使用 SignalR?)
【发布时间】:2013-09-25 06:05:13
【问题描述】:

背景:

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

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

当前的部分解决方案:

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

问题:

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

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

【问题讨论】:

  • 问题 2 可以通过消息总线解决。
  • 对于问题1,客户端发送一个启动任务的请求,MVC 处理该请求并应该发送一个包含taskId 的响应。从新网页开始,SignalR 连接启动,您应该定义一个 Hub 方法,如 Register(taskId),并在服务器上将 taskId 映射到 Context.ConnectionId
  • @Romoku 我不熟悉那是什么。你能提供更多细节吗?
  • @GustavoArmenta 好的,所以服务器向客户端发送回某种方式的任务 ID,然后客户端通过 SignalR 连接并注册其 TaskID,然后将其映射到客户端 ID。然后正在运行的任务使用该映射来发回信息,对吗?但是任务如何访问任务 ID 到客户端 ID 的映射呢?控制器如何访问 SignalR 集线器中的持久数据?
  • 好吧,您可以使用静态 Dictionary 将映射保存在内存中,或者将数据保存到数据库中

标签: c# asp.net-mvc asp.net-mvc-4 signalr signalr.client


【解决方案1】:

我已经为您的需要创建了一个库,它是一个围绕 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

【讨论】:

  • 感谢您的回答!我会在今天晚些时候或明天试一试,然后告诉你进展如何。
【解决方案2】:

对于问题 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 2021-03-02
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多