サーバー 2012 R2、IIS 8.5 で WebSockets が有効になっている SignalR.Redis 2.1.2 で SignalR バージョン 2.1.2 を使用しています。
すべてが私の開発環境で完全に実行されています。同じバックプレーンを使用するように構成されたサイトの異なるサーバー (http machine1/myapp/signalr、http machine2/myapp/signalr など) にコピーを立ち上げることもでき、両方の UI がそれらに完全に発行されたメッセージを取得します。
次に、「myapp」を次の環境に移動しました。これは、F5 ロード バランサーの背後にある 2 台のマシンのクラスターであり、F5 にルーティングするように dns エイリアスを設定し、ラウンド ロビン「myapp」を使用します。Web サイト自体は 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);
}
}
}
}
クライアントのソース コードをダウンロードし、ナゲット パッケージの代わりにそれを直接配線して、すべてをステップ実行できるようにしました。ネゴシエーションに成功し、SSE と LongPolling トランスポートに「接続」しようとしているようですが、両方で失敗しています。
質問 1.1
Signalr for .NET の代替手段を知っている人はいますか。これは、負荷分散によるスケーリングをサポートし、「髪の毛を引き抜きたい」というような方法ではありませんか?