Signalr是以Group、Connect爲核心來進行推送,好比,給某個組、某個鏈接來推送,但實際場景中,核心應該是某個組、某我的;然而一我的能夠對應多個鏈接(瀏覽器多個tab頁);本節就來介紹下自行管理人、組、鏈接這些關係
因爲signalr鏈接的時候不那麼方便附帶header和cookie(由於推送獨立成一個子系統了),實際實現中採用以url query的形式附帶上token,而後服務器端自定義解析token獲得用戶信息;git
ConfigureServices中添加服務相關方法,代碼以下,完整代碼github
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獲得用戶信息web
在Hub中經過Context.User.Identity.Name能夠獲取到解析的值,經過這種關係來跟用戶關聯上,固然,也能夠自定義修改使用其餘信息,好比Email或其餘自定義的名稱,具體請googleredis
更多內容請經過快速導航查看下一篇瀏覽器
標題 | 內容 |
---|---|
索引 | .net core 3.0 Signalr - 實現一個業務推送系統 |
上一篇 | .net core 3.0 Signalr - 04 使用Redis作底板來支持橫向擴展 |
下一篇 | .net core 3.0 Signalr - 06 業務實現-業務分析 |
源碼地址 | 源碼 |
官方文檔 | 官方文檔 |