【问题标题】:SignalR implementing CRUD methods in Hub or ControllerSignalR 在集线器或控制器中实现 CRUD 方法
【发布时间】:2019-07-10 23:00:04
【问题描述】:

我有一个基于 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) 当我在一次 crud 事件后更新仪表板页面上的统计信息时,我认为我构建的结构不同于聊天应用程序。因为我只在 crud 事件之后向 Dashboard 组件发送通知。真的吗?

【问题讨论】:

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


    【解决方案1】:

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

    1) 如果你想要一个简单但有味道的解决方案,那么就这样做吧。但我建议使用 CQRS。 2) 是的:)

    【讨论】:

    • 非常感谢这些有用的信息。我看了一下 CQRS,但目前我们无法切换使用它,因为有几个人在做这个项目。
    • 另一方面,是否有另一种不使用 CQRS 而不是将 CRUD 方法移至 Hub 的智能解决方案?由于 Hub 类不包含 Controller 类所具有的一些方法,所以最好在执行完操作后添加Clients.All.updateStatisticsToPage(record); 行,继续在Controller 中使用相同的方法(创建更新删除)。有可能吗,你能举个例子吗?
    • 创建记录时,通常我会通过实体框架检索最后添加的记录。另一方面,我使用数据库视图来更新我的仪表板。因此,我可以修改我的更新视图并在其中包含统计数据,以便我可以同时将最后添加的 + 统计数据返回到相关页面。
    • 是的,我想过像你描述的那样的解决方案。
    • 是的,我认为这是最好的方法 - 异步调用 Clients.All.updateStatisticsToPage(record); 并忘记它。
    【解决方案2】:

    另一方面,是否有另一种不使用 CQRS 而不是将 CRUD 方法移至 Hub 的智能解决方案?因为Hub类没有包含Controller类的一些方法,所以最好在Controller中继续使用同样的方法(Create Update Delete),添加Clients.All.updateStatisticsToPage(record);操作执行后的行。有可能吗,你能举个例子吗?

    我没有以这种方式使用它,但我认为这是可能的。您可以尝试使用 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);
        }
    }
    

    现在您可以将此集线器作为单例添加到 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连接来接收所有的消息,但我相信你已经知道了。

    【讨论】:

    • 非常感谢您的帮助。除了标记为答案之外,我将尝试应用这种方法并通知您。现在当然投票赞成 x 2 ;)
    • 亲爱的 Beniamin,非常感谢您的帮助。现在我正在改进 Hub 和 Controller 端的代码,并考虑使用上述方法。
    • 但通常我在Transform An Existing MVC App To A Real-Time App Using SignalR 上使用以下方法(只需查看集线器和控制器部分)。那里没有 DI,但我不确定这段代码和你的 Hub & Controller 代码有什么区别?我知道,这段代码不使用 DI,而是使用静态方法并简单地调用它。对利弊有任何想法吗?
    • 有什么帮助吗?
    • 使用 DI,您可以轻松地测试您的代码(轻松地模拟所有依赖项并为控制器中的方法创建单元测试。)。如果你在方法中使用静态对象,那么创建单元测试是不可能的(你不能模拟静态类)。
    猜你喜欢
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多