首页 > 解决方案 > 如何在多台服务器上使用 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; }); 

        });

标签: .net-coresignalrdocker-swarm

解决方案


将 SignalR 扩展到多个服务器时,除了网络考虑之外,还需要一个共享数据平面来管理分布式状态。

文档中所述,Microsoft 建议引入 Redis 背板或委托给他们的托管服务 Azure SignalR。

使用 SignalR 的应用程序需要跟踪其所有连接,这会给服务器场带来问题。添加一个服务器,它会获得其他服务器不知道的新连接。

使用 Azure SignalR 后,与 ASP.NET Core应用程序集成相当简单。然后,您已经从应用程序中卸载了管理连接的所有开销。


推荐阅读