Improving scale out performance for multiple web instances using SignalR Redis Backplane

826 Views Asked by At

I have SignalR integrated in our application, and it has been working just fine. Couple of days ago, due to some requirements, we had to support scale out of our application – and hence we opted for SignalR scale out using Redis.

However, since integration, the SignalR itself has stopped working, and the error we get is : NO TRANSPORT could be initialized successfully. try specifying a different transport or none at all for auto initialization.

Approaches applied : - Tried with different versions of SignalR, as suggested online - Did not help - Increased connection timeout – Did not help

Need some help in resolving this. Suggestion on using any other approach is also welcome.

[Update1] Adding code snippets

public class Startup
{
  public void Configuration(IAppBuilder app)
  {
    // Any connection or hub wire up and configuration should go here
    GlobalHost.DependencyResolver.UseRedis("server", port, "password", "AppName");
    app.MapSignalR();
  }
}

For more reference, I followed this link :https://learn.microsoft.com/en-us/aspnet/signalr/overview/performance/scaleout-with-redis

[Update2]

public void Configuration(IAppBuilder app)
{
 GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(110);
 GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(30);
 GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(10);
 GlobalHost.Configuration.TransportConnectTimeout = TimeSpan.FromSeconds(45);

 ConfigureAuth(app);
 ConfigureSignalR(app);

 // SignalR backplane code changes
 string server = RoleEnvironment.IsAvailable ?
                        RoleEnvironment.GetConfigurationSettingValue(Constant.ConfigKeys.RedisCacheEndpoint) : 
                        ConfigurationManager.AppSettings[Constant.ConfigKeys.RedisCacheEndpoint];
 string port = RoleEnvironment.IsAvailable ?
                      RoleEnvironment.GetConfigurationSettingValue(Constant.ConfigKeys.RedisCachePort) :
                      ConfigurationManager.AppSettings[Constant.ConfigKeys.RedisCachePort];
 string password = RoleEnvironment.IsAvailable ?
                          RoleEnvironment.GetConfigurationSettingValue(Constant.ConfigKeys.RedisCachePassword) :
                          ConfigurationManager.AppSettings[Constant.ConfigKeys.RedisCachePassword];

 const string SIGNALR_REDIS_APPNAME = "Phoenix 2.0 Admin Tool";
 string connectionString = server + ":" + Int32.Parse(port) + ";password=" + password + ",ssl=True,abortConnect=False"; 
 RedisScaleoutConfiguration cfg = new RedisScaleoutConfiguration(connectionString, SIGNALR_REDIS_APPNAME);
 GlobalHost.DependencyResolver.UseRedis(cfg);
 app.MapSignalR();
}
1

There are 1 best solutions below

2
On

We have an Azure AppService and are able to use SignalR w/ the Redis backplane. I did observe that things did not work properly depending on the connection string content. We used the RedisScaleoutConfiguration overload of the GlobalHost.DependencyResolver.UseRedis API instead of using the overload that you show.

Here is a block of code based on our working startup (values changed to protect the vulnerable):

const string SIGNALR_REDIS_APPNAME = "OurAppName";
string connectionString = "thename.redis.cache.windows.net:6380;password=somelongsecret,ssl=True,abortConnect=False";
RedisScaleoutConfiguration cfg = new RedisScaleoutConfiguration(connectionString, SIGNALR_REDIS_APPNAME);
GlobalHost.DependencyResolver.UseRedis(cfg);

Obviously you can get an actual connection string from web.config with more code. We also had trouble when specifying a non-default DB name so are using the default here.

Hope this helps.