簡體   English   中英

在 Asp.Net Core 3.1 中處理 SignalR 集線器中的所有異常

[英]Handle all exceptions in SignalR hubs in Asp.Net Core 3.1

在 Web API 中,所有異常都可以由中間件調用。 在 Asp.Net Core 5.0 中,集線器過濾器將完成這項工作。

但是如何在 SignalR 集線器中處理 Asp.Net Core 3.1 中的異常? 有沒有一種方法可以在下面的每種方法中編寫 try/catch?

[Authorize]
public class OrdersHub : BaseHub
{
        public async Task GetOrder(Guid requestId, int orderId)
        {
            try
            {
                var data = await ordersService.GetOrderAsync(orderId);
                await Clients.Caller.SendAsync("GetOrderResult", requestId, result);
            }
            catch (Exception ex)
            {
                await Clients.Caller.Reject(requestId, ex);
            }
        }
}

您可能知道 ASP.NET SignalR 支持HubPipeline 模塊,這些模塊提供了一種全局處理集線器異常的方法。

但是從這個文檔中我們可以發現 ASP.NET Core SignalR 不再支持 HubPipeline 模塊,目前它似乎沒有提供替代方法來處理全局傳入錯誤。

正如您提到的,我們可以將代碼包裝在 try-catch 塊中並記錄異常對象或手動將其發送給調用者。

請注意,異常通常包含敏感信息,出於安全原因,不建議在生產中向客戶端發送詳細信息。

此外,ASP.NET Core SignalR 提供了內置的診斷日志記錄功能,可以幫助捕獲和記錄有用的傳輸和集線器相關信息,這可以幫助解決問題。

注意:您可以查看討論有關“Signalr .net 核心中央異常處理”的相同要求的github 問題

從 .net 5.0 開始,您可以使用集線器過濾器: https : //docs.microsoft.com/en-us/aspnet/core/signalr/hub-filters?view= aspnetcore-5.0

就我而言,我想記錄在我的 signalr 集線器中拋出的所有未處理的異常。 我正在使用 .NET 6 並執行了以下操作。

  1. 添加 ExceptionFilter.cs。
public class ExceptionFilter : IHubFilter
{
    private readonly ILogger _logger;

    public ExceptionFilter(ILogger logger)
    {
        _logger = logger;
    }

    public async ValueTask<object> InvokeMethodAsync(
        HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next)
    {
        try
        {
            return await next(invocationContext);
        }
        catch (Exception ex)
        {
            _logger.LogError($"Exception calling '{invocationContext.HubMethodName}': {ex}");
            throw;
        }
    }
}
  1. 將 ExceptionFilter 添加到 signalr 選項。
builder.Services.AddSignalR(options =>
{
    options.AddFilter<ExceptionFilter>();
});
  1. 為 DI 注冊 ExceptionFilter。
builder.Services.AddSingleton<ExceptionFilter>();

我通過在集線器方法中手動拋出異常來測試它,然后執行 catch 塊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM