我在 Server 2012 R2 上使用 SignalR 版本 2.1.2 和 SignalR.Redis 2.1.2,IIS 8.5 启用了 WebSockets。
一切都在我的开发环境中完美运行。我什至可以在配置为使用相同背板的站点的不同服务器(例如 http machine1/myapp/signalr、http machine2/myapp/signalr)上建立副本,并且两个 UI 都可以完美地获取发布给它们的消息。
然后,我将“myapp”移动到我们的下一个环境,这是一个由 2 台机器组成的集群,位于 F5 负载均衡器后面,并设置了一个 dns 别名设置以路由到 F5,然后是循环“myapp”。网站本身可以很好地连接到信号器,并且可以接收它订阅的已发布消息,但是当我尝试通过别名(例如 http myappalias/signalr)发布到网站时,我收到 400,错误请求错误响应。这是错误的示例。
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 for .NET 的替代方案,它支持通过负载平衡进行扩展,而不是“我想拔掉头发”的那种方式?