在我们的Visual Studio开发机器前面使用ARR 3.0作为反向代理时,我们无法使SignalR正常工作。连接成功建立但是一旦建立连接就应该从SignalR服务器发送的初始帧永远不会发送,事实上,不能发送任何帧,这会导致客户端丢弃WebSocket连接。总而言之,“websocket连接可以建立,但不能传输帧。”
MVC应用程序无需反向代理即可运行。
我们在以下主题中尝试了所有建议的解决方案:
编辑1
似乎正在发送连接帧但在路上发生故障。通过Wireshark在环回时可以看到它。
编辑2
当我没有在网址上附加后缀时,SignalR似乎与ARR一起使用。换句话说:
答案 0 :(得分:1)
所以,我们设法解决了这个问题,我们挖掘了潜在的原因,以便能够清楚地再现问题。它与重写的顺序有关,我们所做的是我们在ASP.NET MVC应用程序中创建了一个帮助器方法,如果来自orginated请求的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>
我无法解释反向代理和后端Web服务器之间发生的内容导致SignalR帧无法到达但我可以确认所有URL重写都需要在代理中完成并且模拟应用程序中的逻辑相同的重写将无法正常工作,至少不是以上述方式。