Sdílet prostřednictvím


Použití filtrů centra v ASP.NET Core SignalR

Filtry centra:

  • Jsou k dispozici ve verzi ASP.NET Core 5.0 nebo novější.
  • Povolit, aby se logika spouštěla před a po metodách centra klienty.

Tento článek obsahuje pokyny pro psaní a používání filtrů centra.

Konfigurace filtrů centra

Filtry rozbočovačů se dají použít globálně nebo podle typu centra. Pořadí, ve kterém se filtry přidají, je pořadí, ve kterém se filtry spouštějí. Globální filtry centra se spouštějí před filtry místního centra.

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR(options =>
    {
        // Global filters will run first
        options.AddFilter<CustomFilter>();
    }).AddHubOptions<ChatHub>(options =>
    {
        // Local filters will run second
        options.AddFilter<CustomFilter2>();
    });
}

Filtr centra můžete přidat jedním z následujících způsobů:

  • Přidejte filtr podle konkrétního typu:

    hubOptions.AddFilter<TFilter>();
    

    Tento problém se vyřeší prostřednictvím injektáže závislostí (DI) nebo typu aktivovaného.

  • Přidejte filtr podle typu modulu runtime:

    hubOptions.AddFilter(typeof(TFilter));
    

    Tento problém bude vyřešen z di di nebo typu aktivovaného.

  • Přidejte filtr podle instance:

    hubOptions.AddFilter(new MyFilter());
    

    Tato instance se použije jako singleton. Všechny vyvolání metody centra budou používat stejnou instanci.

Filtry centra se vytvářejí a odstraňují na volání centra. Pokud chcete do filtru uložit globální stav nebo žádný stav, přidejte typ filtru centra do DI jako jednoton pro lepší výkon. Případně přidejte filtr jako instanci, pokud je to možné.

Vytvoření filtrů centra

Vytvořte filtr deklarováním třídy, která dědí z IHubFilter, a přidat metodu InvokeMethodAsync . Existují také OnConnectedAsync možnosti, OnDisconnectedAsync které lze volitelně implementovat pro zabalení OnConnectedAsync metod centra a OnDisconnectedAsync centra.

public class CustomFilter : IHubFilter
{
    public async ValueTask<object> InvokeMethodAsync(
        HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next)
    {
        Console.WriteLine($"Calling hub method '{invocationContext.HubMethodName}'");
        try
        {
            return await next(invocationContext);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception calling '{invocationContext.HubMethodName}': {ex}");
            throw;
        }
    }

    // Optional method
    public Task OnConnectedAsync(HubLifetimeContext context, Func<HubLifetimeContext, Task> next)
    {
        return next(context);
    }

    // Optional method
    public Task OnDisconnectedAsync(
        HubLifetimeContext context, Exception exception, Func<HubLifetimeContext, Exception, Task> next)
    {
        return next(context, exception);
    }
}

Filtry jsou velmi podobné middlewaru. Metoda next vyvolá další filtr. Konečný filtr vyvolá metodu centra. Filtry mohou také uložit výsledek čekání next a spuštění logiky po volání metody centra před vrácením výsledku z next.

Chcete-li přeskočit volání metody centra ve filtru, vyvolání výjimky typu HubException namísto volání next. Pokud klient očekával výsledek, zobrazí se chyba.

Použití filtrů centra

Při zápisu logiky filtru zkuste použít obecné atributy v metodách centra místo kontroly názvů metod centra.

Zvažte filtr, který zkontroluje argument metody centra pro zakázané fráze a nahradí všechny fráze, které najde ***. V tomto příkladu předpokládejme, že je definována LanguageFilterAttribute třída. Třída má vlastnost s názvem FilterArgument , kterou lze nastavit při použití atributu.

  1. Umístěte atribut do metody centra, která má řetězcový argument, který se má vyčistit:

    public class ChatHub
    {
        [LanguageFilter(filterArgument = 0)]
        public async Task SendMessage(string message, string username)
        {
            await Clients.All.SendAsync("SendMessage", $"{username} says: {message}");
        }
    }
    
  2. Definujte filtr centra pro kontrolu atributu a nahrazení zakázaných frází v argumentu ***metody centra:

    public class LanguageFilter : IHubFilter
    {
        // populated from a file or inline
        private List<string> bannedPhrases = new List<string> { "async void", ".Result" };
    
        public async ValueTask<object> InvokeMethodAsync(HubInvocationContext invocationContext, 
            Func<HubInvocationContext, ValueTask<object>> next)
        {
            var languageFilter = (LanguageFilterAttribute)Attribute.GetCustomAttribute(
                invocationContext.HubMethod, typeof(LanguageFilterAttribute));
            if (languageFilter != null &&
                invocationContext.HubMethodArguments.Count > languageFilter.FilterArgument &&
                invocationContext.HubMethodArguments[languageFilter.FilterArgument] is string str)
            {
                foreach (var bannedPhrase in bannedPhrases)
                {
                    str = str.Replace(bannedPhrase, "***");
                }
    
                var arguments = invocationContext.HubMethodArguments.ToArray();
                arguments[languageFilter.FilterArgument] = str;
                invocationContext = new HubInvocationContext(invocationContext.Context,
                    invocationContext.ServiceProvider,
                    invocationContext.Hub,
                    invocationContext.HubMethod,
                    arguments);
            }
    
            return await next(invocationContext);
        }
    }
    
  3. Zaregistrujte filtr centra v Startup.ConfigureServices metodě. Aby se zabránilo opětovné inicializaci seznamu zakázaných frází pro každé vyvolání, je filtr centra registrován jako jednoton:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSignalR(hubOptions =>
        {
            hubOptions.AddFilter<LanguageFilter>();
        });
    
        services.AddSingleton<LanguageFilter>();
    }
    

Objekt HubInvocationContext

Obsahuje HubInvocationContext informace o vyvolání aktuální metody centra.

Vlastnost Popis Typ
Context Obsahuje HubCallerContext informace o připojení. HubCallerContext
Hub Instance centra, která se používá pro vyvolání této metody centra. Hub
HubMethodName Název volané metody centra. string
HubMethodArguments Seznam argumentů předávaných metodě centra. IReadOnlyList<string>
ServiceProvider Zprostředkovatel služeb s vymezeným oborem pro vyvolání této metody centra. IServiceProvider
HubMethod Informace o metodě centra. MethodInfo

Objekt HubLifetimeContext

Obsahuje HubLifetimeContext informace o OnConnectedAsync metodách centra a OnDisconnectedAsync centra.

Vlastnost Popis Typ
Context Obsahuje HubCallerContext informace o připojení. HubCallerContext
Hub Instance centra, která se používá pro vyvolání této metody centra. Hub
ServiceProvider Zprostředkovatel služeb s vymezeným oborem pro vyvolání této metody centra. IServiceProvider

Autorizace a filtry

Autorizace atributů u metod centra se spouští před filtry centra.