【问题标题】:How to force a server to send an event-data constantly, using ASP.NET MVC + SignalR?如何使用 ASP.NET MVC + SignalR 强制服务器不断发送事件数据?
【发布时间】:2015-10-01 23:59:10
【问题描述】:

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
}

【问题讨论】:

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


    【解决方案1】:

    最简单的方法是将您的导出客户端作为单例或静态变量,并在全局范围内向您注册事件(可能在 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 设置为永远不会破坏您的应用程序(大多数情况下在共享或云托管上是不可能的),否则您应该尝试使用 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));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-30
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      相关资源
      最近更新 更多