簡體   English   中英

帶有 SignalR 集線器的 ASP.NET Core 中的范圍服務

[英]Scoped services in ASP.NET Core with SignalR Hubs

我已經將 SignalR 引入了我的 ASP.NET Core 2 項目,但是我在使用我通常在我的控制器中使用的范圍服務時遇到了一些問題。 我覺得問題可能是由於 HTTP 請求、websocket 和集線器之間的生命周期不同。

對於每個 HTTP 請求,中間件讀取Authorization令牌並更新請求的范圍服務 ( IUser ) 上的一些屬性(例如 id、聲明等)。 我在所有控制器中使用此服務都沒有問題。 為了讓它與 SignalR 一起工作,我發送了一個access_token查詢參數,並事先使用其他一些中間件將此查詢參數添加為一個可以正常工作的標頭。

當我嘗試訪問 SignalR 集線器中的IUser服務時會出現問題。 在構建集線器時,被注入的IUser沒有設置任何屬性,盡管/hub請求的中間件只是設置了它們。

如果我將服務設置為單例,則它可以工作,但IUser持續時間不應超過單個請求。

我應該如何為特定 SignalR 連接設置IUser

// Startup.cs - User has several settable properties 
services.AddScoped<IUser, User>();
// User Middleware
public class UserMiddleware
{
    private readonly RequestDelegate _next;

    public UserMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext context)
    {
        // retrieve service for this request
        var user = context.RequestServices.GetService<IUser>();

        // set some properties on the User from auth token
        // e.g. User.Id = 1;

        return _next(context);
    }
}
[Authorize(Roles = Claim.Names.Read)]
public class MyHub : Hub
{
    private readonly IUser _user;

    public MyHub(IUser user)
    {
        // user that gets injected has null properties
        _user = user;
    }

    public async Task Foo()
    {
        // do work with the _user credentials
    }
}
public class DownloadController : Controller
{
    private readonly IUser _user;

    public DownloadController(IUser user)
    {
        // user gets injected and has properties set
        _user = user;
    }
}

您是否在 Hub 方法中嘗試過Context.GetHttpContext().RequestServices 那應該是正在進行的請求的IServiceProvider

要在信號器集線器中使用范圍服務,您可以注入ServiceProvider並直接在其中創建一個范圍:

public class ChatHub : Hub
{      
    private IServiceProvider _serviceProvider;
    public ChatHub(IServiceProvider serviceProvider)
    {
        _serviceProvider= serviceProvider;
    }

    public async Task Foo()
    {
        using (var scope = _serviceProvider.CreateScope())
        {
           var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

           var user = scope.ServiceProvider.GetRequiredService<IUser>();    

        }

    }
}

暫無
暫無

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

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