.net-core - 如何在多台服务器上使用 SignalR?
问题描述
我有一个使用 dotnet core、singalR 和 react native 制作的聊天应用程序。当我在单个服务器上发布聊天时,我的聊天运行良好。但是当我通过 docker swarm在多个服务器上发布它时。我得到这个错误。
无法使用任何可用的传输连接到服务器。WebSockets 失败:错误:传输出现错误。
通过此错误消息,该应用程序有时只能正常工作。当我离开页面并返回时,它不再工作。
我正在使用 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 扩展到多个服务器时,除了网络考虑之外,还需要一个共享数据平面来管理分布式状态。
如文档中所述,Microsoft 建议引入 Redis 背板或委托给他们的托管服务 Azure SignalR。
使用 SignalR 的应用程序需要跟踪其所有连接,这会给服务器场带来问题。添加一个服务器,它会获得其他服务器不知道的新连接。
使用 Azure SignalR 后,与 ASP.NET Core应用程序集成相当简单。然后,您已经从应用程序中卸载了管理连接的所有开销。
推荐阅读
- php - 如何通过网站的所有链接保持“推荐人”属性?
- python - 指定 Tensorflow 随机均匀的最大值向量
- python-3.x - 如何将列表列表中的项目与列表中的项目进行比较?
- javascript - 在 Node 服务器上进行 API 调用并将结果分配给类属性
- spring-boot - 使用Spring Data JPA,什么情况下应该直接使用EntityManager?
- sql - 根据另一个表的不同日期计算一个表的出现次数
- firebase - 使用 Cloud Firestore 后端时迁移到新数据模型的最佳做法
- javascript - 未捕获的 ReferenceError:在 svelte/sapper 中未定义 require
- typescript - 使用 Appium 的移动自动化,使用 Typescript 的 WebdriverIO
- csv - 显示带有别名的分发列表