简体   繁体   English

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

[英]Synchronizing client state between SignalR and ASP.NET MVC4 (or should I even use SignalR?)

Background: 背景:

Here's my project: On an ASP.NET MVC4 web app, users enter information and post to the server. 这是我的项目:在ASP.NET MVC4 Web应用程序上,用户输入信息并发布到服务器。 The server then starts running a long task (anywhere from less than a second to 20 minutes. Usually about 4 minutes.) 然后,服务器开始运行长任务(从不到一秒到20分钟的任何时间。通常大约4分钟。)

I don't want all of the work happening in the Controller action, or else the user would have to wait for it to complete with no feedback about what's going on. 我不希望在Controller动作中发生所有工作,否则用户将不得不等待其完成,而对正在发生的事情没有任何反馈。 So I'd like to send the user to a status page and send updates from the server to that page. 因此,我想将用户发送到状态页面,并将更新从服务器发送到该页面。

Current Partial Solution: 当前的部分解决方案:

Here's what I have so far: The Controller starts a Task with the long running action and then directs the user to the status page. 到目前为止,这是我的工作:控制器使用长时间运行的操作启动任务,然后将用户定向到状态页面。 As the task runs, it sends messages back to the status page with SignalR, and the page updates. 任务运行时,它将使用SignalR将消息发送回状态页面,并且页面将更新。

Problems: 问题:

  1. SingalR is updating all Clients, so more than one user can't use this app at the same time. SingalR正在更新所有客户端,因此多个用户不能同时使用此应用程序。 I see that SignalR has a way to send messages to specific clients, but how can I get the client ID to the Controller? 我看到SignalR可以将消息发送到特定客户端,但是如何将客户端ID发送到Controller? SignalR makes it difficult (impossible?) to access the Session. SignalR使得访问会话变得困难(不可能?)。
  2. What if the Task finishes before the status page loads (or what if there's a pause between updates right as the page loads?) The status page won't have any information about the Task. 如果任务在状态页加载之前完成了(或者在页面加载时两次更新之间有暂停)怎么办?状态页将没有有关任务的任何信息。 Again, it would be nice to store the status the Session, but I can't seem to make that work. 同样,最好将状态存储为Session,但我似乎无法使该工作正常。

Is there a way to get SignalR and ASP.NET to synchronize client state? 有没有办法让SignalR和ASP.NET同步客户端状态? Is SignalR the right tool for the job? SignalR是适合该工作的工具吗?

I have made a Library for just what you need, its a wrapper library around SignalR. 我已经根据您的需要制作了一个库,它是SignalR的包装库。 It requires you to have somekind of message bus / event aggregator. 它要求您具有某种消息总线/事件聚合器。 My library then proxies between your message bus and SignalR clients. 然后,我的库在您的消息总线和SignalR客户端之间进行代理。

This way your background worker can in a easy way send progress reports both to other components of back end and to the clients seamless. 这样,您的后台工作人员可以轻松地将进度报告发送到后端的其他组件以及无缝发送给客户端。

Install using nuget 使用nuget安装

Install-Package SignalR.EventAggregatorProxy

You need to implement a service bus / event aggregator. 您需要实现服务总线/事件聚合器。 Caliburn Micro has a light footprint one Caliburn Micro的占地面积很小

Install-Package Caliburn.Micro.EventAggregator

Follow the wiki how to set it up 按照Wiki进行设置

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

Once your done with setting it up you can listen to events like this from javascript 完成设置后,您可以从javascript收听此类事件

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

Forgot to mention that there is a Demo project here https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/tree/master/SignalR.EventAggregatorProxy.Demo.MVC4 忘了提及这里有一个演示项目https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/tree/master/SignalR.EventAggregatorProxy.Demo.MVC4

For Problem1, Client sends a request to start a task, MVC processes the request and should send a response containing a taskId. 对于问题1,客户端发送一个开始任务的请求,MVC处理该请求,并应发送一个包含taskId的响应。 From the new webpage, a SignalR connection is started and you should define a Hub Method like Register(taskId) and on server map the taskId to Context.ConnectionId – Gustavo Armenta Aug 29 at 19:04 从新的网页开始,SignalR连接开始,您应该定义一个集线器方法,例如Register(taskId),并在服务器上将taskId映射到Context.ConnectionId – Gustavo Armenta,8月29日,19:04

@GustavoArmenta Ok, so the server sends the client back some manner of ID for the task, the client then connects through SignalR and registers its TaskID, which is then mapped to the client ID. @GustavoArmenta好的,因此服务器将客户端的某种任务ID发送回去,然后客户端通过SignalR连接并注册其TaskID,然后将其映射到客户端ID。 Then the running task uses that mapping to send information back, right? 然后,正在运行的任务使用该映射将信息发送回去,对吗? But how does the task access the mapping of task ID to client ID? 但是任务如何访问任务ID到客户端ID的映射? How does a Controller access persistent data in a SignalR hub? 控制器如何访问SignalR集线器中的持久数据? – Danation Aug 29 at 19:15 – Danation 8月29日19:15

Well, you could save the mapping on memory with a static Dictionary or persist data to a database – Gustavo Armenta Aug 30 at 16:47 好吧,您可以使用静态字典将映射保存在内存中或将数据持久保存到数据库中– Gustavo Armenta,8月30日,16:47

@GustavoArmenta, I ended up going with your option (I was able to fix both problems.) If you add it as an answer, I will accept it. @GustavoArmenta,我最后选择了您的选择(我能够解决两个问题。)如果您将其添加为答案,我会接受的。 – Danation Sep 18 at 4:17 – Danation 9月18日4:17

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM