zoukankan      html  css  js  c++  java
  • asp.net core 使用 signalR(一)

    asp.net core 使用 signalR(一)

    Intro

    SignalR 是什么?

    ASP.NET Core SignalR 是一个开源代码库,它简化了向应用添加实时 Web 功能的过程。 实时 Web 功能使服务器端代码能够即时将内容推送到客户端。

    SignalR 的适用对象:

    • 需要来自服务器的高频率更新的应用。 例如:游戏、社交网络、投票、拍卖、地图和 GPS 应用。
    • 仪表板和监视应用。 示例包括公司仪表板、销售状态即时更新或行程警示。
    • 协作应用。 协作应用的示例包括白板应用和团队会议软件。
    • 需要通知的应用。 社交网络、电子邮件、聊天、游戏、行程警示以及许多其他应用都使用通知。

    SignalR 提供了一个用于创建服务器到客户端远程过程调用(RPC)的 API。 RPC 通过服务器端 .NET Core 代码调用客户端上的 JavaScript 函数。

    以下是 ASP.NET Core SignalR 的一些功能:

    • 自动管理连接。

    • 同时向所有连接的客户端发送消息。 例如,聊天室。

    • 将消息发送到特定的客户端或客户端组。

    • 扩展以处理增加的流量。

    传输

    SignalR 支持几种方法用于处理实时通信:

    • WebSockets

    • 服务器发送事件

    • 长轮询

      SignalR 会从服务器和客户端支持的功能中自动选择最佳传输方法

    最近我们在做一个对战的小游戏,类似于之前比较火的答题应用,使用 websocket 来实现客户端和服务器端的通信,服务器端使用的 SignalR

    SignR 基本使用

    服务注册

    服务配置如下:

    services.AddSignalR(options =>
        {
            options.HandshakeTimeout = TimeSpan.FromSeconds(3);
            options.KeepAliveInterval = TimeSpan.FromSeconds(10);
        })
        // JSON 序列化配置
        .AddJsonProtocol(options =>
        {
            options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
            options.PayloadSerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
            options.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            options.PayloadSerializerSettings.NullValueHandling = NullValueHandling.Ignore;
        });
    
    

    认证方式配置

    默认的 Token 是从请求头 Authorization 中获取的,而 signalr 请求服务器端的时候是放在请求地址的 query string access-token 里面的,所以我们要配置从请求头中获取或者从 QueryString 里获取,示例配置如下:

    services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddIdentityServerAuthentication(options =>
        {
            options.Authority = Configuration["Authorization:Authority"];
            options.RequireHttpsMetadata = false;
    
            options.TokenRetriever = request =>
            {
                var token = TokenRetrieval.FromAuthorizationHeader()(request);
                if (string.IsNullOrWhiteSpace(token))
                {
                    token = TokenRetrieval.FromQueryString()(request);
                }
    
                return token;
            };
        });
    

    Configue 配置

    
    app.UseAuthentication();
    
    app.UseSignalR(builder =>
    {
        builder.MapHub<QuizGameHub>("/hubs/quizGame"); // 注册 Hub
    });
    
    app.UseMvc();
    

    自定义 Hub

    定义 Hub 契约

    定义一个客户端方法的接口以实现强类型的客户端方法调用,这里客户端调用服务器端的方法也定义了一个接口来约束,示例如下:

    /// <summary>
    /// 客户端定义的方法
    /// </summary>
    public interface IQuizGameClient
    {
        Task GameQuestionsReceived(QuizQuestion question);
    
        Task MatchSuccess(GameInfo gameInfo);
    
       Task GameAnswerResultReceived(CheckedUserQuizAnswerModel answer);
    
        Task GameOver(GameResult result);
    }
    
    /// <summary>
    /// 服务器端定义的方法
    /// </summary>
    public interface IQuizGameServer
    {
        Task<ServiceResult<IReadOnlyList<QuizGameRuleInfo>>> GetGameRules();
    
        Task AutoMatch(int ruleId);
    
        Task CheckQuestionAnswer(BaseQuizAnswer model, string gameId);
    }
    

    定义 Hub

    有了契约之后,我们就可以定义强类型的 Hub 了,示例如下:

    [Authorize(Policy = "bearer")]
    public partial class QuizGameHub : Hub<IQuizGameClient>, IQuizGameServer
    {
    
        public Task<ServiceResult<IReadOnlyList<QuizGameRuleInfo>>> GetGameRules()
        {
            return Task.FromResult(ServiceResult.Success(QuizGameStorage.GameRuleInfos));
        }
        
        // ...
    
        public async Task CheckQuestionAnswer(BaseQuizAnswer model, string gameId)
        {
            // 调用客户端方法
            await Clients.User(Context.UserIdentifier)
            	.GameAnswerResultReceived(checkedResult); // 向指定用户发送消息
        }
        
        public async Task AutoMatch(int ruleId)
        {
            // ...
        }
    }
    

    Reference

  • 相关阅读:
    Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
    Python学习之字典详解
    IDEA启动服务慢的问题处理
    IDEA部署Tomcat应用所有接口中文乱码
    为什么选择微信公众号而不是小程序的考虑要素
    Vue基础及脚手架环境搭建
    VSCode集成Git代码管理
    VSCode开发工具下载
    U盘装系统:安装GHOST Win7系统教程
    前端资源管理工具sourcetree
  • 原文地址:https://www.cnblogs.com/weihanli/p/use-signalr-in-aspnetcore.html
Copyright © 2011-2022 走看看