微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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 支持几种方法用于处理实时通信:

最近我们在做一个对战的小游戏,类似于之前比较火的答题应用,使用 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐