zoukankan      html  css  js  c++  java
  • .net core 3.0 Signalr

    Signalr是以Group、Connect为核心来进行推送,比如,给某个组、某个连接来推送,但实际场景中,核心应该是某个组、某个人;然而一个人可以对应多个连接(浏览器多个tab页);本节就来介绍下自行管理人、组、连接这些关系
    由于signalr连接的时候不那么方便附带header和cookie(因为推送独立成一个子系统了),实际实现中采用以url query的形式附带上token,然后服务器端自定义解析token得到用户信息;

    服务器端实现

    • ConfigureServices中添加服务相关方法,代码如下,完整代码
      public void ConfigureServices(IServiceCollection services)
      {
          var appSection = Configuration.GetSection("App");
          services.Configure<AppSetting>(option => appSection.Bind(option));
          var appSetting = appSection.Get<AppSetting>();
      
          services.AddSingleton<SignalrRedisHelper>();
      
          // services.AddHostedService<ClearBackGroundService>();
      
          services.AddAuthentication(options =>
          {
              options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
              options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
              options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
          })
          .AddJwtBearer(option =>
          {
              option.SecurityTokenValidators.Clear();
              option.SecurityTokenValidators.Add(new UserTokenValidation()); ;
      
              option.Events = new JwtBearerEvents()
              {
                  OnMessageReceived = context =>
                  {
                      var userId = context.Request.Query["userId"].FirstOrDefault();
                      if (!string.IsNullOrWhiteSpace(userId))
                      {
                          context.Token = userId;
                      }
                      return Task.CompletedTask;
                  }
              };
          });
      
          services.AddCors(options => options.AddPolicy(corsPolicy, builder =>
          {
              builder
                    .SetIsOriginAllowedToAllowWildcardSubdomains()
                    .WithOrigins(appSetting.CORS.Split(","))
                    .AllowAnyMethod()
                    .AllowCredentials()
                    .AllowAnyHeader()
                    .Build();
          }));
      
          services.AddControllers()
              .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
              .ConfigureApiBehaviorOptions(options =>
              {
                  options.InvalidModelStateResponseFactory = context =>
                  {
                      var result = new BadRequestObjectResult(context.ModelState);
                      result.ContentTypes.Add(MediaTypeNames.Application.Json);
                      // result.ContentTypes.Add(MediaTypeNames.Application.Xml);
      
                      return result;
                  };
              })
              .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
      
          // 添加Signalr
          services.AddSignalR(config =>
          {
              if (_webEnv.IsDevelopment())
              {
                  config.EnableDetailedErrors = true;
              }
          })
          // 支持MessagePack
          .AddMessagePackProtocol()
          // 使用redis做底板 支持横向扩展 Scale-out
          .AddStackExchangeRedis(o =>
            {
                o.ConnectionFactory = async writer =>
                {
                    var config = new ConfigurationOptions
                    {
                        AbortOnConnectFail = false,
                        // Password = "changeme",
                        ChannelPrefix = "__signalr_",
                    };
                    //config.EndPoints.Add(IPAddress.Loopback, 0);
                    //config.SetDefaultPorts();
                    config.DefaultDatabase = appSetting.SignalrRedisCache.DatabaseId;
                    var connection = await ConnectionMultiplexer.ConnectAsync(appSetting.SignalrRedisCache.ConnectionString, writer);
                    connection.ConnectionFailed += (_, e) =>
                    {
                        Console.WriteLine("Connection to Redis failed.");
                    };
      
                    if (connection.IsConnected)
                    {
                        Console.WriteLine("connected to Redis.");
                    }
                    else
                    {
                        Console.WriteLine("Did not connect to Redis");
                    }
      
                    return connection;
                };
            });
      }
      

    其中,SignalrRedisHelper 为redis辅助方法,详情请参见
    UserTokenValidation 为自定义token解析方法,详情请参见,由于历史遗留问题,此处直接使用了userId,建议的做法是传递jwttoken,然后服务器端解析jwt token得到用户信息

    Hub中跟用户关联

    在Hub中通过Context.User.Identity.Name可以获取到解析的值,通过这种关系来跟用户关联上,当然,也可以自定义修改使用其他信息,比如Email或其他自定义的名称,具体请google

    更多内容请通过快速导航查看下一篇

    快速导航

    标题 内容
    索引 .net core 3.0 Signalr - 实现一个业务推送系统
    上一篇 .net core 3.0 Signalr - 04 使用Redis做底板来支持横向扩展
    下一篇 .net core 3.0 Signalr - 06 业务实现-业务分析
    源码地址 源码
    官方文档 官方文档

    二维码

  • 相关阅读:
    java代码--Date类获取当前时间-格式化输出
    Eclipse快速生成do while if 等方法
    java不同包中protected修饰的属性和方法调用方法
    java中如果删除导入的jar包,工程出现叹号解决方案
    Best Reward HDU 3613(回文子串Manacher)
    Teacher YYF
    Period II
    How many
    String Problem
    Corporate Identity
  • 原文地址:https://www.cnblogs.com/xiexingen/p/11626394.html
Copyright © 2011-2022 走看看