ASP.NET核心SignalR OnDisconnectedAsync未通过集线器[已授权]启动



.net core 2.1

集线器代码:

[Authorize]    
public class OnlineHub : Hub
{
public override async System.Threading.Tasks.Task OnConnectedAsync()
{
int userId = Context.UserIdentifier;
await base.OnConnectedAsync();
}
[AllowAnonymous]
public override async System.Threading.Tasks.Task OnDisconnectedAsync(Exception exception)
{
var b = Context.ConnectionId;
await base.OnDisconnectedAsync(exception);
}

客户代码:

$(document).ready(() => {
let token = "token";
const connection = new signalR.HubConnectionBuilder()
.withUrl("https://localhost:44343/online", { accessTokenFactory: () => token })
.configureLogging(signalR.LogLevel.Debug)
.build();
connection.start().catch(err => console.error(err.toString()));
});

除了OnConnectedAsync中的Context.UserIdentifier之外,没有Authorize]一切都很好,这是可以解释的,但是。。。使用Hub类上的[Authorize]属性,OnConnectedAsync开始工作,并且OnDisconnected根本不触发,包括30秒超时(默认情况下(。

有什么想法吗?

如果连接了调试器并通过关闭浏览器选项卡关闭客户端,则永远不会看到OnDisconnectedAsync被激发。这是因为SignalR会检查是否附加了调试器,并且不会触发某些超时,以使调试更容易。如果您通过在客户端上调用stop来关闭,那么您应该会看到调用了OnDisconnectedAsync

添加

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecurityKey"]))
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});

这将触发SignalR集线器中的OnDisconnectedAsync

对于blazor实现此代码

@implements IAsyncDisposable

并粘贴此函数。编码

public async ValueTask DisposeAsync()
{
if (hubConnection is not null)
{
await hubConnection.DisposeAsync();
}
}

这似乎是一个非常古老的问题,但我会添加一些关于故障排除的经验,也许它会帮助某人一次。在调查了signalR javascript客户端在使用Authorize属性和HTTP连接进行消息传递时为什么没有导致OnDisconnectedAsync之后,我发现它发送到服务器的DELETE方法被CORS策略阻止了。因此,您可以查看请求响应,如果请求被CORS限制而被阻止,则很可能需要在CORS策略中允许DELETE(以及OPTIONS(方法。

最新更新