Я использую SignalR версии 2.1.2 с SignalR.Redis 2.1.2 на сервере 2012 R2, IIS 8.5 с включенными WebSockets.
Все работает отлично в моей среде разработки. Я даже могу размещать копии на разных серверах (например, http machine1/myapp/signalr, http machine2/myapp/signalr) сайта, настроенного на использование одной и той же объединительной платы, и оба пользовательских интерфейса получают сообщения, публикуемые для них идеально.
Затем я переместил «myapp» в нашу следующую среду, которая представляет собой кластер из 2 машин, стоящих за балансировщиком нагрузки F5, с настройкой псевдонима dns для маршрутизации к F5, а затем циклическим перебором «myapp». Сам веб-сайт может нормально подключаться к signalr и может получать опубликованные сообщения, на которые он подписан, НО, когда я пытаюсь опубликовать на сайте через псевдоним (например, http myappalias/signalr), я получаю ответ об ошибке 400, Bad Request. Вот пример ошибки.
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
}
Вот некоторый тестовый код, который я использую для публикации тестовых сообщений в каждой среде, где он не работает на "connection.Start().Wait()"
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);
}
}
Теперь, если я не использую «myappalias», а вместо этого ударяю по серверу, он работает отлично. Похоже, проблема либо в F5, либо в этом сценарии клиент должен быть настроен по-другому, либо мне нужно сделать что-то другое при настройке класса запуска Signlar. Вот пример класса запуска, который я использую.
[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);
}
}
}
}
Я загружаю исходный код клиента и подключаю его напрямую вместо пакета nuget, чтобы я мог пройти через все. Кажется, он успешно согласовывает, а затем пытается «подключиться» к SSE, а затем к транспорту LongPolling, но терпит неудачу в обоих случаях.
Вопрос 1.1
Кто-нибудь знает альтернативу Signalr для .NET, которая поддерживает масштабирование с балансировкой нагрузки менее «я хочу рвать на себе волосы»?