gpt4 book ai didi

c# - F5 后面带有 Redis 背板的 SignalR - StatusCode : 400, ReasonPhrase: 'Bad Request'

转载 作者:行者123 更新时间:2023-11-30 12:27:04 26 4
gpt4 key购买 nike

我在 Server 2012 R2、启用了 WebSockets 的 IIS 8.5 上使用 SignalR 版本 2.1.2 和 SignalR.Redis 2.1.2。

一切都在我的开发环境中完美运行。我什至可以在不同的服务器(例如 http machine1/myapp/signalr、http machine2/myapp/signalr)上建立站点配置为使用相同背板的副本,并且两个 UI 都可以完美地向它们发布消息。

然后我将“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 for .NET 的替代品,它支持以一种不那么“我想拔头发”的方式通过负载平衡进行缩放?

最佳答案

应该没有必要配置源地址亲和性以在负载平衡器后面使用 SignalR。设置 session 亲和性当然没有错,但这并不能解决您的根本问题。

如果您仔细查看 400 响应的内容,您可能会看到类似于“The ConnectionId 格式不正确”的消息。

SignalR 使用服务器的机器 key 来创建反 CSRF token ,但这需要您场中的所有服务器共享一个机器 key ,以便在 SignalR 请求跃点服务器时正确解密 token 。您看到成功的/negotiate 请求是检索反 CSRF token 的请求。当 SignalR 客户端随后使用反 CSRF token 发出/connect 请求时,它失败了,因为/connect 请求由未创建 token 且无法解密的不同服务器处理。

这解释了为什么设置 session 亲和性可以解决您的问题,但共享机器 key 将帮助您避免此问题,即使 session 亲和性出现问题也是如此。

这是一个遇到类似问题的人在 GitHub 上提交的问题:https://github.com/SignalR/SignalR/issues/2292 .

关于c# - F5 后面带有 Redis 背板的 SignalR - StatusCode : 400, ReasonPhrase: 'Bad Request',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26920269/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com