title: SignalR with Redis Backplane Behind F5 - StatusCode: 400, ReasonPhrase: 'Bad Request'
body: <p>I'm using SignalR version 2.1.2 with SignalR.Redis 2.1.2 on Server 2012 R2, IIS 8.5 with WebSockets enabled.</p>
  
  <p>All is running perfectly in my development environment. I can even stand up copies on different servers (e.g. http machine1/myapp/signalr, http machine2/myapp/signalr) of the site configured to use the same backplane, and both UI's get messages pubb'd to them perfectly.</p>
  
  <p>I then moved "myapp" to our next environment, which is a cluster of 2 machines sitting behind an F5 load balancer, with a dns alias setup to route to the F5, and then round robin "myapp". The website itself can connect to signalr just fine, and can receive published messages it subscribes to, BUT when I try to publish to the site via the alias (e.g. http myappalias/signalr), I get a 400, Bad Request error response. Here is an example of the error.</p>
  
  <pre><code>  InnerException: Microsoft.AspNet.SignalR.Client.Infrastructure.StartException
         _HResult=-2146233088
         _message=Error during start request. Stopping the connection.
         HResult=-2146233088
         IsTransient=false
         Message=Error during start request. Stopping the connection.
         InnerException: System.AggregateException
              _HResult=-2146233088
              _message=One or more errors occurred.
              HResult=-2146233088
              IsTransient=false
              Message=One or more errors occurred.
              InnerException: Microsoft.AspNet.SignalR.Client.HttpClientException
                   _HResult=-2146233088
                   _message=StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
  {
    Pragma: no-cache
    Transfer-Encoding: chunked
    X-Content-Type-Options: nosniff
    Persistent-Auth: true
    Cache-Control: no-cache
    Date: Thu, 13 Nov 2014 22:30:22 GMT
    Server: Microsoft-IIS/8.5
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Content-Type: text/html
    Expires: -1
  }
  </code></pre>
  
  <p>Here is some test code I'm using to publish test messages to each environment, where it fails on "connection.Start().Wait()"</p>
  
  <pre><code>class Program
  {
      static void Main(string[] args)
      {
          var connection = new HubConnection("http://myappalias/signalr");
  
          connection.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
  
          var proxy = connection.CreateHubProxy("MyAppHub");
  
          connection.Start().Wait();
  
          ConsoleKeyInfo key = Console.ReadKey();
  
          do
          {
  
  
              proxy.Invoke("NewMessage", new Message() { Payload = "Hello" });
  
              Console.WriteLine("Message fired.");
  
              key = Console.ReadKey();
  
          } while (key.Key != ConsoleKey.Escape);
      }
  }
  </code></pre>
  
  <p>Now, if I don't use the "myappalias", and instead hit the server head on, it works perfectly. It appears either the F5 is the problem, the client needs to be configured differently for this scenario or I have to do something different when setting up signlar's startup class. Here is an example of the startup class I'm using.</p>
  
  <pre><code>[assembly: OwinStartup(typeof(MyApp.Startup))]
  namespace MyApp
  {
      public class Startup
      {
          private static readonly ILog log = LogManager.GetLogger
          (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  
          public void Configuration(IAppBuilder app)
          {
              try
              {
                  log.Debug(LoggingConstants.Begin);
  
                  string redisServer = ConfigurationManager.AppSettings["redis:server"];
  
                  int redisPort = Convert.ToInt32(ConfigurationManager.AppSettings["redis:port"]);
  
                  HubConfiguration configuration = new HubConfiguration();
                  configuration.EnableDetailedErrors = true;
                  configuration.EnableJavaScriptProxies = false;
                  configuration.Resolver = GlobalHost.DependencyResolver.UseRedis(redisServer, redisPort, string.Empty, "MyApp");
  
                  app.MapSignalR("/signalr", configuration);   
  
                  log.Info("SIGNALR - Startup Complete");
              }
              finally
              {
                  log.Debug(LoggingConstants.End);
              }
          }
  
      }
  
  }
  </code></pre>
  
  <p>I download the client source code, and wired that in directly instead of the nuget package, so I could step through everything. I seems it successfully negotiates, and then attempt to "connect" with SSE's and then LongPolling transports, but fails at both.</p>
  
  <p><strong>Question 1.1</strong></p>
  
  <p>Anyone know of an alternative to Signalr for .NET that supports scaling with load balancing in a less "I want to pull my hair out" kind of way?</p>