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

标签 c# .net asp.net-mvc event-handling signalr

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

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

Controller 代码:

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 的 Application_Start() 方法中。 CS)。您的集线器代码也应该移出,因为集线器像 Controller 一样是 transient 的。

这是它的样子:

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 设置为永不拆除您的应用程序(大多数情况下在共享或云托管上是不可能的),否则您应该尝试使用 HangFire可作为 nuget package 使用的库.它是专门为该用例设计的,经过一些重构,您的代码可能如下所示:

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

关于c# - 如何使用 ASP.NET MVC + SignalR 强制服务器不断发送事件数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32898596/

相关文章:

javascript - 使用信号器更新数据库更改时如何刷新 View

c# - MethodInfo.Invoke 性能问题

c# - 从基类继承

asp.net-mvc - 在某些 View 中隐藏渲染页面 Razor

c# - TreeNodeCollection.ContainsKey() 的问题

c# - System.Reactive 3.0 中缺少 Observable 类和 ToObservable

c# - Process.WaitForExit 跨机器不一致

html - 无法将控件添加到我的 ASP 页面中的现有 DIV 元素

asp.net-mvc - ASP.Net MVC成员资格

c# - 使用 HAVING COUNT 对 NHibernate 的 SQL 查询