因此,我们设法解决了相关问题,并深入挖掘了根本原因,以便能够清楚地重现问题。它与完成重写的顺序有关,我们所做的是我们在 ASP.NET MVC 应用程序中创建了一个辅助方法,如果来自发起请求的 HTTP 标头包含我们的重写路径,它将重写输入参数 URL后缀。
public static class RouteHelper
{
public static string Url(string url)
{
string orginalUrl = HttpContext.Current?.Request.Headers["X-Original-URL"];
if (!string.IsNullOrEmpty(orginalUrl))
{
if (orginalUrl.StartsWith("/" + "portal", true, CultureInfo.InvariantCulture)
|| orginalUrl.StartsWith("portal", true, CultureInfo.InvariantCulture))
{
url = "/" + "portal" + url;
}
}
return url;
}
}
我们使用此方法设置 SignalR 集线器/连接的 URL,如下所示:
$.connection.hub.url = '@RouteHelper.Url("/signalr")'
结果将是 $.connection.hub.url = '@RouteHelper.Url("/portal/signalr")'
很容易认为这会产生与创建出站重写规则相同的结果,但这是不正确的。
代理返回给客户端的响应是一样的,但是代理和后端网络服务器之间的通信会发生故障。
相反,我们为此创建了一个出站规则,如下所示:
<rule name="SignalRReverseProxySignalRHubsUrl">
<match filterByTags="None" pattern="connection.hub.url.*=.*['\"](.*)['\"]" />
<action type="Rewrite" value="connection.hub.url = "/portal{R:1}"" />
</rule>
我无法解释导致 SignalR 帧未到达的反向代理和后端 Web 服务器之间内部发生的情况,但我可以确认所有 URL 重写都需要在代理和模拟应用程序中的逻辑上完成相同的重写将无法正常工作,至少不能以上述方式。