ASP.NET Core SignalR 系列(四)- 中心筛选器

这篇具有很好参考价值的文章主要介绍了ASP.NET Core SignalR 系列(四)- 中心筛选器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本章将和大家分享 ASP.NET Core SignalR 中的中心筛选器。

本文大部分内容摘自微软官网:https://learn.microsoft.com/zh-cn/aspnet/core/signalr/hub-filters?view=aspnetcore-7.0

废话不多说,下面我们直接进入本章主题。

中心筛选器:

  • 在 ASP.NET Core 5.0 或更高版本中可用。
  • 允许在客户端调用中心方法之前和之后运行逻辑。

1、创建中心筛选器

通过声明从 IHubFilter 继承的类来创建筛选器,并添加 InvokeMethodAsync 方法。 还可以选择实现 OnConnectedAsync 和 OnDisconnectedAsync,以分别包装 OnConnectedAsync 和 OnDisconnectedAsync 中心方法。

using Microsoft.AspNetCore.SignalR;

namespace SignalRChat.HubFilter
{
    public class CustomFilter : IHubFilter
    {
        public async ValueTask<object> InvokeMethodAsync(HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next)
        {
            System.Diagnostics.Debug.WriteLine($"Calling hub method '{invocationContext.HubMethodName}'");
            try
            {
                var result = await next(invocationContext); //调用下一个筛选器,最终筛选器将调用中心方法
                System.Diagnostics.Debug.WriteLine($"Called hub method '{invocationContext.HubMethodName}'");
                return result;
            }
            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);
        }
    }
}

筛选器与中间件非常相似。 next 方法调用下一个筛选器。 最终筛选器将调用中心方法。 筛选器还可以存储等待 next 的结果,并在调用中心方法之后、从 next 返回结果之前运行逻辑。

若要跳过筛选器中的中心方法调用,请引发 HubException 类型的异常,而不是调用 next。 如果客户端需要结果,则会收到错误。

2、配置中心筛选器

中心筛选器可以全局应用或按中心类型应用。 筛选器的添加顺序就是其运行顺序。 全局中心筛选器在本地中心筛选器之前运行。

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

可以通过以下方式之一添加中心筛选器:

1)按具体类型添加筛选器:

hubOptions.AddFilter<TFilter>();

将通过依赖项注入 (DI) 或激活的类型来解析。

2)按运行时类型添加筛选器:

hubOptions.AddFilter(typeof(TFilter));

将通过 DI 或激活的类型来解析。

3)按实例添加筛选器:

hubOptions.AddFilter(new MyFilter());

将像单一实例一样使用此实例。 所有中心方法调用都将使用相同的实例。

系统根据中心调用来创建和释放中心筛选器。 如果要在筛选器中存储全局状态,或者不存储状态,请将中心筛选器类型作为单一实例添加到 DI,以获得更好的性能。 或者,如果可以,将筛选器添加为实例。

3、使用中心筛选器

编写筛选器逻辑时,请尝试通过在中心方法上使用特性而不是检查中心方法名称,使其成为泛型逻辑。

以某个筛选器为例,该筛选器将检查中心方法参数中是否有被禁短语,并将找到的任何短语替换为 ***。 对于此示例,假设定义了 LanguageFilterAttribute 特性类。 该类有一个名为 FilterArgument 的属性,可以在使用该属性时对其进行设置。

1)将该特性标签打在需要清理字符串参数的中心方法上:

public class ChatHub
{
    [LanguageFilter(filterArgument = 0)]
    public async Task SendMessage(string message, string username)
    {
        await Clients.All.SendAsync("SendMessage", $"{username} says: {message}");
    }
}

2)定义一个中心筛选器,以检查该特性并将中心方法参数中的被禁短语替换为 ***:

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)在 Startup.ConfigureServices 方法中注册中心筛选器。 为了避免每次调用都重新初始化被禁短语列表,中心筛选器将注册为单一实例:

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

    services.AddSingleton<LanguageFilter>();
}

4、HubInvocationContext 对象

HubInvocationContext 包含当前中心方法调用的信息。

属性 说明 类型
 Context  HubCallerContext 包含有关连接的信息。  HubCallerContext
 Hub  用于此中心方法调用的中心实例。  Hub
 HubMethodName  正在调用的中心方法的名称。  string
 HubMethodArguments  传递给中心方法的参数列表。  IReadOnlyList<string>
 ServiceProvider  用于此中心方法调用的已限定范围的服务提供程序。  IServiceProvider
 HubMethod  中心方法信息。  MethodInfo

5、HubLifetimeContext 对象

HubLifetimeContext 包含 OnConnectedAsync 和 OnDisconnectedAsync 中心方法的信息。

属性 说明 类型
Context HubCallerContext 包含有关连接的信息。 HubCallerContext
Hub 用于此中心方法调用的中心实例。 Hub
ServiceProvider 用于此中心方法调用的已限定范围的服务提供程序。 IServiceProvider

6、授权和筛选器

中心方法上的 Authorize 属性在中心筛选器之前运行。

至此本文就全部介绍完了,想要了解更多内容可参考微软官网。

 

Demo源码:文章来源地址https://www.toymoban.com/news/detail-570091.html

链接:https://pan.baidu.com/s/1la_AnXNqsXWRG0bslh5dFg 
提取码:54kz

到了这里,关于ASP.NET Core SignalR 系列(四)- 中心筛选器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ASP.NET Core SignalR 系列(三)- JavaScript 客户端

    本章将和大家分享 ASP.NET Core SignalR 中的 JavaScript 客户端。ASP.NET Core SignalR JavaScript 客户端库使开发人员能够调用服务器端SignalR中心代码。 本文大部分内容摘自微软官网:https://learn.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-7.0tabs=visual-studio 废话不多说,下面我们

    2024年02月15日
    浏览(33)
  • 【EasyExcel】导出excel冻结表头和冻结指定列并支持筛选器

    需求背景:         导出excel的同时冻结表头和前两列基础信息,方便导出后用户查看信息。 一、技术选型:         easyExcel的自定义写策略处理:SheetWriteHandler 二、方案设计:(基于实现 SheetWriteHandler 接口)         1、重写afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder,

    2024年01月24日
    浏览(33)
  • ASP.NET Core SignalR 入门

    本章将和大家分享使用 SignalR 生成实时应用的基础知识。通过本文您将学习如何:使用ASP.NET Core SignalR + MVC + Vue 2.x + require 最终创建一个正常运行的简易聊天应用。 废话不多说,我们直接来看一个Demo,Demo的目录结构如下所示: 本Demo的Web项目为ASP.NET Core Web 应用程序( 目标框

    2024年02月11日
    浏览(31)
  • 什么是 ASP.NET Core SignalR?

    所有连接了 Internet 的应用程序都由服务器和客户端组成。 客户端依赖于服务器获取数据,而它们获取数据的主要机制是通过发出超文本传输协议 (HTTP) 请求来进行的。 某些客户端应用程序需要经常更改的数据。 ASP.NET Core SignalR 提供了一个 API,用于创建服务器到客户端远程过

    2024年02月15日
    浏览(23)
  • ASP.NET Core实时库SignalR简单应用

    SignalR 是用于构建需要实时用户交互或实时数据更新的Web 应用程序的一个开放源代码.NET 库。不仅仅用在Web应用中,后面会讲到它的应用范围。它简化了简化了构建实时应用程序的过程,包括 ASP.NET Server 库和 JavaScript Client 库,以便管理Client与Server连接并将内容更新推送给Cl

    2024年02月11日
    浏览(61)
  • ASP.NET Core+Vue3 实现SignalR通讯

    从ASP.NET Core 3.0版本开始,SignalR的Hub已经集成到了ASP.NET Core框架中。因此,在更高版本的ASP.NET Core中,不再需要单独引用Microsoft.AspNetCore.SignalR包来使用Hub。 在项目创建一个类继承Hub, 首先是写一个CreateConnection方法 ConnectionId是SignalR中标识的客户端连接的唯一标识符, 将userId和

    2024年02月06日
    浏览(34)
  • 【ASP.NET Core】使用SignalR推送服务器日志

    一个多月前接手了一个产线机器人项目,上位机以读写寄存器的方式控制机器人,服务器就是用 ASP.NET Core 写的 Web API。由于前一位开发者写的代码质量问题,导致上位机需要16秒才能启动。经过我近一个月的改造,除了保留业务逻辑代码,其他的基本重写。如今上位机的启动

    2024年02月03日
    浏览(43)
  • Web SSH 的原理与在 ASP.NET Core SignalR 中的实现

    有个项目,需要在前端有个管理终端可以 SSH 到主控机的终端,如果不考虑用户使用 vim 等需要在控制台内现实界面的软件的话,其实使用 Process 类型去启动相应程序就够了。而这次的需求则需要考虑用户会做相关设置。 这里用到的原理是伪终端。伪终端(pseudo terminal)是现

    2024年02月07日
    浏览(52)
  • 微信小程序如何使用原生Websocket与Asp.Net Core SignalR 通信

    如题,这可能算是.net 做小程序的服务端时,绕不开的一个问题,老生常谈了。同样的问题,我记得我2018/19年的一个项目的解决方案是: 修改官方的SignalR.js的客户端 :把里面用到浏览器的Websocket改成微信小程序的官方api的。目前网上也有不少这样的方案,已经改好开源了;

    2024年02月08日
    浏览(42)
  • 微信小程序如何使用原生Websocket api与Asp.Net Core SignalR 通信

    如题,这可能算是.net 做小程序的服务端时,绕不开的一个问题,老生常谈了。同样的问题,我记得我2018/19年的一个项目的解决方案是: 修改官方的SignalR.js的客户端 :把里面用到浏览器的Websocket改成微信小程序的官方api的。目前网上也有不少这样的方案,已经改好开源了;

    2024年02月09日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包