SignalR在集线器或控制器中实现CRUD方法

时间:2019-07-10 11:06:49

标签: c# asp.net asp.net-mvc angular signalr

我有一个基于ASP.NET MVC应用程序的Angular应用程序,还有一个仪表板,在其中显示一些在创建/更新/删除事件中更改的平均值和总数。通常,这些事件在Controller中实现,如下所示:

Controller.cs:

[HttpPost]
public JsonResult Create(Record record)
{
    // code omitted for brevity
    return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
}

[HttpPost]
public JsonResult Update(Record record)
{
    // code omitted for brevity
    return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
}

[HttpPost]
public JsonResult Delete(int id)
{
    // code omitted for brevity
    return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
}

但是,在执行完这些方法之后,我需要调用相应的Hub方法以更新“仪表板”页面上的数字。


Hub.cs:

public class NotificationHub : Hub
{
    public void Update(Record record)
    {
        Clients.All.updateStatisticsToPage(record);
    }
}

所以,我的问题是:

1)如何合并这些方法以更新“仪表盘”页面上的数字?我应该将CRUD方法移至集线器并仅使用这种方法吗?我添加了最后一行,以通知客户有关当前统计数据的信息。

[HttpPost]
public JsonResult Create(Record record)
{
    // code omitted for brevity
    return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);

    // send update to all clients
    Clients.All.updateStatisticsToPage(record);
}

还是应该在执行crud操作之后将该方法保留在Controller方法中并调用hub方法?

2)在发生严重事件后更新“仪表板”页面上的统计信息时,我认为我构建的结构不同于聊天应用程序。因为我仅在事件发生后才将通知发送到仪表板组件。真的吗?

2 个答案:

答案 0 :(得分:1)

如果要使用SignalR,我建议使用CQRS架构模式。它将解决您的问题。在垂直切片的体系结构中,您将看到向所有客户端发送通知的最佳位置。

1)如果您想要一个简单但有气味的解决方案,请以这种方式进行。但是我建议使用CQRS。 2)是:)

答案 1 :(得分:1)

  

另一方面,是否存在另一个不使用CQRS而不是将CRUD方法移到集线器的智能解决方案?因为集线器类不包含Controller类具有的某些方法,所以最好通过添加Clients.All.updateStatisticsToPage(record)在Controller中继续使用相同的方法(“创建更新删除”)。该操作执行后的一行。有可能,请您举个例子吗?

我不是那样使用它的,但我认为这是可能的。您可以尝试使用IStatisticsHub接口创建StatisticsHub:

public interface IStatisticsHub
{
    Task Send(string message);
}

public class StatisticHub : Microsoft.AspNetCore.SignalR.Hub, IStatisticsHub
{
    private readonly IHubContext<StatisticHub > _context;

    public StatisticHub(IHubContext<EventTypeHub> context)
    {
        _context = context;
    }

    public async Task Send(string message)
    {
        await _context.Clients.All.SendAsync("Send", message);
    }
}

现在,您可以将该中心作为Singleton添加到DI容器中

services.AddSingleton<IStatisticsHub, StatisticHub>();

最后一步是将该集线器注入您的控制器:

public class Controller : ControllerBase
{
    private readonly IStatisticsHub _statisticsHub;

    public Controller(IStatisticsHub statisticsHub)
    {
        _statisticsHub = statisticsHub;
    }

    [HttpPost]
    public JsonResult Update(Record record)
    {
        // code omitted for brevity

        // send message to all clients
        _statisticsHub.Send("Statistics");

        return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
    } 
}

它应该以这种方式工作。

首先,前端必须与此集线器创建WebSocket连接以接收所有消息,但我相信您已经知道了。