如何在多个服务器上使用 SignalR?
How to use SignalR on multiple servers?
我有一个聊天应用程序,是我用 dotnet core、singalR 和 React Native 制作的。当我在单个服务器上发布聊天时,它运行良好。但是当我通过 docker 群在 多个 服务器上发布它时。我收到此错误。
无法使用任何可用传输连接到服务器。 WebSockets 失败:错误:传输出错。
通过此错误消息,该应用程序有时会正常运行。当我离开页面并 return 返回时,它不再工作了。
我正在使用 ubuntu 服务器。我都在服务器和客户端上调整了 signalR 的版本。他们都在使用 5.0.3。我在应用程序前面没有代理服务器,我正在使用 docker swarm 的负载平衡功能。
配置服务
var tokenKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["TokenKey"]));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = tokenKey,
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
opt.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken))
{
if (path.StartsWithSegments("/chat")
|| path.StartsWithSegments("/dialog"))
{
context.Token = accessToken;
}
}
return Task.CompletedTask;
}
};
});
配置虚空
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chat", opt => { opt.Transports = HttpTransportType.WebSockets; });
endpoints.MapHub<DialogHub>("/dialog", opt => { opt.Transports = HttpTransportType.WebSockets; });
});
将 SignalR 扩展到多个服务器时,除了网络注意事项外,还需要共享数据平面来管理分布式状态。
如 docs 中所述,Microsoft 建议引入 Redis 背板或委托给他们的托管服务 Azure SignalR。
An app that uses SignalR needs to keep track of all its connections,
which creates problems for a server farm. Add a server, and it gets
new connections that the other servers don't know about.
使用过 Azure SignalR,integrate with an ASP.NET Core 应用程序相当简单。然后,您就可以从应用程序中卸载管理连接的所有开销。
我有一个聊天应用程序,是我用 dotnet core、singalR 和 React Native 制作的。当我在单个服务器上发布聊天时,它运行良好。但是当我通过 docker 群在 多个 服务器上发布它时。我收到此错误。
无法使用任何可用传输连接到服务器。 WebSockets 失败:错误:传输出错。
通过此错误消息,该应用程序有时会正常运行。当我离开页面并 return 返回时,它不再工作了。
我正在使用 ubuntu 服务器。我都在服务器和客户端上调整了 signalR 的版本。他们都在使用 5.0.3。我在应用程序前面没有代理服务器,我正在使用 docker swarm 的负载平衡功能。
配置服务
var tokenKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["TokenKey"]));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = tokenKey,
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
opt.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken))
{
if (path.StartsWithSegments("/chat")
|| path.StartsWithSegments("/dialog"))
{
context.Token = accessToken;
}
}
return Task.CompletedTask;
}
};
});
配置虚空
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chat", opt => { opt.Transports = HttpTransportType.WebSockets; });
endpoints.MapHub<DialogHub>("/dialog", opt => { opt.Transports = HttpTransportType.WebSockets; });
});
将 SignalR 扩展到多个服务器时,除了网络注意事项外,还需要共享数据平面来管理分布式状态。
如 docs 中所述,Microsoft 建议引入 Redis 背板或委托给他们的托管服务 Azure SignalR。
An app that uses SignalR needs to keep track of all its connections, which creates problems for a server farm. Add a server, and it gets new connections that the other servers don't know about.
使用过 Azure SignalR,integrate with an ASP.NET Core 应用程序相当简单。然后,您就可以从应用程序中卸载管理连接的所有开销。