[英]How to force a server to send an event-data constantly, using ASP.NET MVC + SignalR?
ExportClient
class has OnTickRecieved
event, which helps me to receive some data (bid prices from market). ExportClient
类具有OnTickRecieved
事件,这有助于我接收一些数据(来自市场的出价)。 All I want - is to receive this data real-time on my charts in browser. 我想要的只是在浏览器的图表上实时接收这些数据。 When I press
Go
button on UI-side, it calls Go()
method in controller, and then nothing is happening. 当我在UI端按下
Go
按钮时,它在控制器中调用Go()
方法,然后什么也没发生。 And it's logical - because after request on server, controller is destroyed. 这是合乎逻辑的 - 因为在服务器上请求后,控制器被销毁。
My question is: how to force a server to send me an event-data constantly? 我的问题是:如何强制服务器不断向我发送事件数据?
Controller code: 控制器代码:
public class ChartsController : Controller
{
[HttpGet]
public void Go()
{
var exportClient = new ExportClient();
exportClient.TickRecieved += exportClient_TickRecieved;
}
private void exportClient_TickRecieved(object sender, TickRecievedEventArgs args)
{
ImpulserHub.SendBidPrice(args.Bid);
}
}
Hub code: 中心代码:
[HubName("impulserHub")]
public class ImpulserHub : Hub
{
public static void SendBidPrice(double bid)
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ImpulserHub>();
hubContext.Clients.All.sendBidPrice(bid);
}
}
And I have tested SignalR, this code works fine: 我已经测试了SignalR,这段代码工作正常:
[HttpGet]
public void Go()
{
ImpulserHub.SendBidPrice(3.3333333); // I have received this number on UI
}
The simplest way would be to have your export client as a singleton or as a static variable and register to you event in the global scope (probably in your Application_Start()
method from Global.asax.cs). 最简单的方法是将导出客户端作为单例或静态变量,并在全局范围内注册到您的事件(可能在Global.asax.cs的
Application_Start()
方法中)。 Your hub code should also be moved out since hubs are transient like controllers. 您的集线器代码也应该移出,因为集线器像控制器一样是瞬态的。
This is how it would look like: 这是它的样子:
private ExportClient _exportClient;
private IHubContext _impulserHub;
protected void Application_Start()
{
_exportClient = new ExportClient();
exportClient.TickRecieved += exportClient_TickRecieved;
_impulserHub = GlobalHost.ConnectionManager.GetHubContext<ImpulserHub>();
}
private void exportClient_TickRecieved(object sender, TickRecievedEventArgs args)
{
_impulserHub.Clients.All.sendBidPrice(args.Bid);
}
There is still an issue remaining with this code. 此代码仍然存在问题。 IIS will tear down websites that are not actively receiving requests.
IIS将拆除未主动接收请求的网站。 This means that the code may stop working at any time even if the event is triggered.
这意味着即使事件被触发,代码也可能随时停止工作。 Managing application teardown is hard since the state must be saved/transferred between application start and stop.
管理应用程序拆卸很困难,因为必须在应用程序启动和停止之间保存/转移状态。 Unless you can set IIS never to tear down your application (most of the time impossible on shared or cloud hosting), you should try to use the HangFire library which is available as a nuget package .It was specifically designed for that use case and with a bit of refactoring, your code could look like that:
除非您可以设置IIS永远不会拆除您的应用程序(大多数时候在共享或云托管上不可能),您应该尝试使用可作为nuget包提供的HangFire库。它是专门为该用例而设计的一点点重构,你的代码看起来像这样:
private ExportClient _exportClient;
private IHubContext _impulserHub;
protected void Application_Start()
{
_exportClient = new ExportClient();
exportClient.TickRecieved += exportClient_TickRecieved;
_impulserHub = GlobalHost.ConnectionManager.GetHubContext<ImpulserHub>();
BackgroundJob.Schedule(() => _impulserHub.Clients.All.sendBidPrice(_exportClient.GetBid()), TimeSpan.FromSeconds(5));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.