问题描述
我将SignalR Core添加到了Asp.net Core 3 Web Api项目中,该Web api与我的Android应用程序进行通信,我试图在两个客户端之间来回发送消息,并且我不想使用connection_Id因为当用户离开进行连接的活动时,如果客户端重新连接,连接将丢失并且connection_Id将更改,在这种情况下,两个用户之间的通信将丢失,第二个用户将无法通信与第一个用户在一起,因为另一个用户的connectionId已更改,所以我想使用userName或userId在用户之间发送消息
PS:当我向所有客户端发送消息或使用connectionId发送代码时,效果很好。
PS:我正在使用身份和JWT对我的应用程序中的用户进行身份验证和授权。所以我在Hub中有此方法:
public async Task sendOffer(DeliveryOffer offer)
{
string name= Context.User.Identity.Name;
Notifications notification = new Notifications();
notification.deliveryOffer = offer;
await Clients.User(name).SendAsync("sendOfferToClient",notification);
}
这是mycustomerUserIdProvider:
public class CustomUserIdProvider : IUserIdProvider
{
public virtual string GetUserId(HubConnectionContext connection)
{
return connection.User.Identity.Name;
}
}
在我的启动类的configure方法中,我在添加Authentication之后添加了signalR,如下所示:
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSignalR(routes => {
routes.MapHub<NotificationHub>("/myHub");
});
services.AddSignalR();
services.AddSingleton<IUserIdProvider,CustomUserProvider>();
但是此指令始终返回null:
string id = Context.User.Identity.Name; // Always null
private TokenResponse generatetoken(User user)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_jwtSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new System.Security.Claims.ClaimsIdentity(new[]
{
new Claim(JwtRegisteredClaimNames.Aud,user.Email),new Claim(JwtRegisteredClaimNames.Sub,new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),new Claim(JwtRegisteredClaimNames.Email,new Claim(JwtRegisteredClaimNames.UniqueName,user.UserName)
new Claim(JwtRegisteredClaimNames.NameId,user.UserName),new Claim(ClaimTypes.NameIdentifier,}),Expires = DateTime.UtcNow.AddMinutes(10),SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),SecurityAlgorithms.HmacSha256)
};
var token = tokenHandler.Createtoken(tokenDescriptor);
TokenResponse response = new TokenResponse();
response.token = tokenHandler.Writetoken(token);
return response;
}
public void ConfigureServices(IServiceCollection services)
{
JwtSettings jwtSettings = new JwtSettings();
Http_Client http_client = new Http_Client();
Configuration.Bind(nameof(jwtSettings),jwtSettings);
services.AddIdentity<SuperUser,IdentityRole<int>>()
.AddEntityFrameworkStores<AkdContext>()
.AddUserManager<CustomUserManager>();
services.Configure<IdentityOptions>(options =>
{
});
services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.Savetoken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtSettings.Secret)),ValidateIssuer = false,ValidateAudience = false,Validissuer = Configuration["JwtSettings:Issuer"],ValidAudience = Configuration["JwtSettings:Issuer"],RequireExpirationTime = false,ClockSkew = TimeSpan.FromMinutes(60),ValidateLifetime = true,};
x.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accesstoken = context.Request.Query["access_token"];
// If the request is for our hub...
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accesstoken) &&
(path.StartsWithSegments("/myHub")))
{
// Read the token out of the query string
context.Token = accesstoken;
}
return Task.CompletedTask;
}
};
});
services.AddAuthorization();
services.AddSingleton<IUserIdProvider,CustomUserProvider>();
services.AddSignalR();
services.AddMvc();
services.AddDbContext<AkdContext>();
services.AddControllers();
services.AddSingleton(jwtSettings);
services.AddTransient<IHttp_Client,Http_Client>();
//services.AddTransient<ICommandRepository,CommandRepository>();
//services.AddTransient<ICommandService,CommandService>();
services.AddTransient<IOrderRequestRepository,OrderRequestRepository>();
services.AddTransient<IOrderRequestService,OrderRequestService>();
services.AddTransient<INotificationRepository,NotificationRepository>();
services.AddTransient<INotificationService,NotificationService>();
services.AddAutoMapper(typeof(Startup));
}
and this is the Configure method :
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSignalR(routes => {
routes.MapHub<NotificationHub>("/myHub");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",template: "{controller}/{action}/{id?}");
});
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)