Aracılığıyla paylaş


ASP.NET Core'da hub filtrelerini kullanma SignalR

Hub filtreleri:

  • ASP.NET Core 5.0 veya sonraki sürümlerde kullanılabilir.
  • İstemciler tarafından hub yöntemleri çağrılmadan önce ve sonra mantığın çalıştırılmasına izin verin.

Bu makalede hub filtrelerini yazma ve kullanma yönergeleri sağlanır.

Hub filtrelerini yapılandırma

Hub filtreleri genel olarak veya hub türü başına uygulanabilir. Filtrelerin eklenme sırası, filtrelerin çalıştırıldığı sıradır. Genel hub filtreleri yerel hub filtrelerinin öncesinde çalışır.

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>();
    });
}

Hub filtresi aşağıdaki yollardan biriyle eklenebilir:

  • Somut türe göre filtre ekleyin:

    hubOptions.AddFilter<TFilter>();
    

    Bu, bağımlılık ekleme (DI) veya etkinleştirilmiş türle çözülür.

  • Çalışma zamanı türüne göre filtre ekleyin:

    hubOptions.AddFilter(typeof(TFilter));
    

    Bu, DI veya tür etkinleştirildiğinde çözülür.

  • Örneğe göre filtre ekleyin:

    hubOptions.AddFilter(new MyFilter());
    

    Bu örnek tekil gibi kullanılacaktır. Tüm hub yöntemi çağrıları aynı örneği kullanır.

Hub filtreleri hub çağrısı başına oluşturulur ve atılır. Genel durumu filtrede depolamak veya durum depolamak istemiyorsanız, daha iyi performans için hub filtre türünü tekil olarak DI'ye ekleyin. Alternatif olarak, varsa filtreyi örnek olarak ekleyin.

Hub filtreleri oluşturma

öğesinden IHubFilterdevralan bir sınıf bildirerek bir filtre oluşturun ve yöntemini ekleyin InvokeMethodAsync . Ayrıca OnConnectedAsync , ve OnDisconnectedAsync hub yöntemlerini sırasıyla sarmak OnConnectedAsync için isteğe bağlı olarak uygulanabilen ve OnDisconnectedAsync de vardır.

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);
    }
}

Filtreler ara yazılıma çok benzer. yöntemi sonraki next filtreyi çağırır. Son filtre hub yöntemini çağırır. Filtreler ayrıca hub yöntemi çağrıldıktan sonra beklenip next çalıştırılan sonucu da nextdepolayabilir.

Bir filtrede hub yöntemi çağırmayı atlamak için çağrısı nextyerine türünde HubException bir özel durum oluşturun. İstemci bir sonuç bekliyorsa bir hata alır.

Hub filtrelerini kullanma

Filtre mantığını yazarken, hub yöntemi adlarını denetlemek yerine hub yöntemlerinde öznitelikleri kullanarak genel hale getirmeye çalışın.

Yasaklanmış tümcecikler için hub yöntemi bağımsız değişkenlerini denetleyecek ve bulduğu tümcecikleri ile ***değiştirecek bir filtre düşünün. Bu örnekte bir LanguageFilterAttribute sınıfın tanımlandığını varsayalım. sınıfı, özniteliği kullanılırken ayarlanabilen adlı FilterArgument bir özelliğe sahiptir.

  1. özniteliğini, temizlenecek bir dize bağımsız değişkeni olan hub yöntemine yerleştirin:

    public class ChatHub
    {
        [LanguageFilter(filterArgument = 0)]
        public async Task SendMessage(string message, string username)
        {
            await Clients.All.SendAsync("SendMessage", $"{username} says: {message}");
        }
    }
    
  2. Özniteliği denetlemek için bir hub filtresi tanımlayın ve bir hub yöntemi bağımsız değişkenindeki yasaklanmış tümcecikleri ile ***değiştirin:

    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. Hub filtresini yöntemine Startup.ConfigureServices kaydedin. Yasaklanan tümcecikler listesinin her çağrı için yeniden başlatılmasını önlemek için hub filtresi tekil olarak kaydedilir:

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

HubInvocationContext nesnesi

geçerli HubInvocationContext hub yöntemi çağırma bilgilerini içerir.

Özellik Açıklama Type
Context bağlantı HubCallerContext hakkında bilgi içerir. HubCallerContext
Hub Bu hub yöntemi çağırma için kullanılan Hub örneği. Hub
HubMethodName Çağrılan hub yönteminin adı. string
HubMethodArguments Hub yöntemine geçirilen bağımsız değişkenlerin listesi. IReadOnlyList<string>
ServiceProvider Bu hub yöntemi çağırma için kapsamlı hizmet sağlayıcısı. IServiceProvider
HubMethod Hub yöntemi bilgileri. MethodInfo

HubLifetimeContext nesnesi

ve HubLifetimeContextOnDisconnectedAsync hub yöntemlerine OnConnectedAsync ilişkin bilgileri içerir.

Özellik Açıklama Type
Context bağlantı HubCallerContext hakkında bilgi içerir. HubCallerContext
Hub Bu hub yöntemi çağırma için kullanılan Hub örneği. Hub
ServiceProvider Bu hub yöntemi çağırma için kapsamlı hizmet sağlayıcısı. IServiceProvider

Yetkilendirme ve filtreler

Hub yöntemlerindeki yetkilendirme öznitelikleri, hub filtrelerinden önce çalıştırılır.