繁体   English   中英

如何使用ASP.NET MVC + SignalR强制服务器不断发送事件数据?

[英]How to force a server to send an event-data constantly, using ASP.NET MVC + SignalR?

ExportClient类具有OnTickRecieved事件,这有助于我接收一些数据(来自市场的出价)。 我想要的只是在浏览器的图表上实时接收这些数据。 当我在UI端按下Go按钮时,它在控制器中调用Go()方法,然后什么也没发生。 这是合乎逻辑的 - 因为在服务器上请求后,控制器被销毁。

我的问题是:如何强制服务器不断向我发送事件数据?

控制器代码:

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);
    }
}

中心代码:

[HubName("impulserHub")]
public class ImpulserHub : Hub
{
   public static void SendBidPrice(double bid)
   {
       var hubContext = GlobalHost.ConnectionManager.GetHubContext<ImpulserHub>();
       hubContext.Clients.All.sendBidPrice(bid);
   }
}

我已经测试了SignalR,这段代码工作正常:

[HttpGet]
public void Go()
{
   ImpulserHub.SendBidPrice(3.3333333); // I have received this number on UI
}

最简单的方法是将导出客户端作为单例或静态变量,并在全局范围内注册到您的事件(可能在Global.asax.cs的Application_Start()方法中)。 您的集线器代码也应该移出,因为集线器像控制器一样是瞬态的。

这是它的样子:

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);
}

此代码仍然存在问题。 IIS将拆除未主动接收请求的网站。 这意味着即使事件被触发,代码也可能随时停止工作。 管理应用程序拆卸很困难,因为必须在应用程序启动和停止之间保存/转移状态。 除非您可以设置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.

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