我有一个基于 SignalR 的 .NET 4.5 应用程序。服务器后端是用 C# 编写的,我只有 Javascript 客户端连接到我的集线器。目前我正在测试最新的 SignalR 版本 2.2.2。
我的应用程序通常托管在较旧的 Windows Server 2008 R2 和 IIS 7.5 上,而且我的用户也在 IE10 或 IE11 上。这会减少对 foreverFrame 和 longPolling 的可用传输。
最近我们开始收到更多关于 JS 客户端断开连接的报告。我很快注意到 ForeverFrame 不再工作了,所有的 JS 客户端都在使用 longPolling。
这个问题现在专门针对 ForeverFrame 不起作用(如有必要,我将发布一个关于 longPolling 问题的单独问题)。
以下是我如何重现该问题(foreverFrame 传输不起作用):
- 我的应用程序在 Windows Server 2008 R2 和 IIS 7.5 上运行(服务器定期使用安全和关键补丁进行修补)
- 使用 IE11 访问我的测试页面
- 远程连接(换句话说,不是从服务器本地连接)
- 在控制台中我看到:SignalR:尝试连接时,foreverFrame 传输超时。"
- SignalR 回退到 longPolling,它开始正常
- 在集线器方面,我已经覆盖了 OnConnected 和 OnDisconnected,有趣的是我没有看到 OnConnected 触发,但 OnDisconnected 触发了
- 在 Developer Tools Network 选项卡中,我看到 foreverFrame 的 (Abort):
URL Protocol Method Result Type Received Taken Initiator Wait Start Request Response Cache read Gap /MMCI/signalr/connect?transport=foreverFrame&clientProtocol=1.5&connectionToken=4MQ9IexTBePfDa7ilqJuKLoxAW5cpgSSK171zjD18vmXtdEKNEIWyFnFYYWlEKjTt49Ou9lLps961D3LTMxGNzW0GzIlBsLtmIA%2BgVQZz0nL71f6fK6jkfrOn5dcHoyz&connectionData=%5B%5D&tid= 10&frameId=1 HTTP (Aborted) 0 B < 1 ms 帧导航 484 0 0 0 0 5335
有趣的是,如果我在本地连接,则不会发生此问题。我什至可以在本地的旧服务器上使用 IE8,并且 foreverFrame 启动正常。或者我可以在我的笔记本电脑上本地使用 IE11 并在 IIS Express 上运行我的应用程序,一切都很好。但是当我远程浏览到我的网站时,foreverFrame 无法启动。
值得一提的是我的 ConnectionTest.html 的代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SignalR Connection Test</title>
<script src="Scripts/jquery-1.12.4.min.mjs"></script>
<script src="Scripts/jquery.signalR-2.2.2.min.mjs"></script>
<script src="signalr/hubs"></script>
</head>
<body>
<script type="text/javascript">
$(function () {
var chat = $.connection.MMCIChatHub; // Declare a proxy to reference the hub
$.connection.hub.logging = true;
$.connection.hub.start({ transport: ['webSockets', 'foreverFrame', 'longPolling'] })
.done(function () {
//Observe console and network tabs in Developer Tools
});
});
</script>
</body>
</html>
这也是刷新我的测试页面时来自 IE11 的完整调试控制台输出:
HTML1300: Navigation occurred.
File: ConnectionTest.html
[23:30:52 GMT+0300 (FLE Daylight Time)] SignalR: Window unloading, stopping the connection.
[23:30:52 GMT+0300 (FLE Daylight Time)] SignalR: Stopping connection.
[23:30:52 GMT+0300 (FLE Daylight Time)] SignalR: Aborted xhr request.
[23:30:52 GMT+0300 (FLE Daylight Time)] SignalR: Fired ajax abort async = false.
[23:30:53 GMT+0300 (FLE Daylight Time)] SignalR: No hubs have been subscribed to.
The client will not receive data from hubs.
To fix, declare at least one client side
function prior to connection start for each
hub you wish to subscribe to.
[23:30:53 GMT+0300 (FLE Daylight Time)] SignalR: Negotiating with '/MMCI/signalr/negotiate?clientProtocol=1.5
&connectionData=%5B%5D'.
[23:30:53 GMT+0300 (FLE Daylight Time)] SignalR: foreverFrame transport starting.
[23:30:53 GMT+0300 (FLE Daylight Time)] SignalR: Binding to iframe's load event.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: foreverFrame transport timed out when trying to connect.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: Stopping forever frame.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: foreverFrame transport failed to connect. Attempting to fall back.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: longPolling transport starting.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: Opening long polling request to
'http://217.77.198.140/MMCI/signalr/connect?transport=longPolling&
clientProtocol=1.5&connectionToken=y3tVestYFcE9jSYGTtsg5PL9tkVRmuKE1a%2F
yd%2BllR6ZwaNzXO3%2BI%2F
wGZfYTp9k4xzqy2Wb4mwxAawmfwG3Nh0c4Hq9LG75qDGtjk0FZ1hPUecK0udIUt2bay%2B
EfCKcAL&connectionData=%5B%5D'.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: Long poll complete.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: LongPolling connected.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: longPolling transport connected. Initiating start request.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: Opening long polling request to
'http://217.77.198.140/MMCI/signalr/poll?transport=longPolling&
clientProtocol=1.5&connectionToken=y3tVestYFcE9jSYGTtsg5PL9tkVRmuKE1a%2F
yd%2BllR6ZwaNzXO3%2BI%2F
wGZfYTp9k4xzqy2Wb4mwxAawmfwG3Nh0c4Hq9LG75qDGtjk0FZ1hPUecK0udIUt2bay%2B
EfCKcAL&connectionData=%5B%5D'.
[23:30:58 GMT+0300 (FLE Daylight Time)] SignalR: The start request succeeded. Transitioning to the connected state.
这是从服务器本身在本地访问相同的 URL 时 IE8 的输出(相同的结果在我的笔记本电脑上本地发生,带有 IE11 和 IIS Express):
LOG: [23:35:16 UTC+0300] SignalR: Window unloading, stopping the connection.
LOG: [23:35:16 UTC+0300] SignalR: Stopping connection.
LOG: [23:35:16 UTC+0300] SignalR: Stopping forever frame.
LOG: [23:35:16 UTC+0300] SignalR: Fired ajax abort async = false.
LOG: [23:35:16 UTC+0300] SignalR: Stopping the monitoring of the keep alive.
LOG: [23:35:16 UTC+0300] SignalR: No hubs have been subscribed to. The client will not receive data from hubs.
To fix, declare at least one client side function prior to connection
start for each hub you wish to subscribe to.
LOG: [23:35:16 UTC+0300] SignalR: Negotiating with '/MMCI/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%5D'.
LOG: [23:35:16 UTC+0300] SignalR: foreverFrame transport starting.
LOG: [23:35:16 UTC+0300] SignalR: Binding to iframe's load event.
LOG: [23:35:16 UTC+0300] SignalR: Iframe transport started.
LOG: [23:35:16 UTC+0300] SignalR: foreverFrame transport connected. Initiating start request.
LOG: [23:35:16 UTC+0300] SignalR: The start request succeeded. Transitioning to the connected state.
LOG: [23:35:16 UTC+0300] SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive
timeout of 20000 and disconnecting timeout of 30000
所以....有什么想法吗?:)
更新: 我可以反过来测试:使用 IE8 从 Win2008R2 服务器连接到笔记本电脑上的 IIS Express。在这种情况下,ForeverFrame 完全正常启动。所以目前这似乎是一个 IE11 问题。试图弄清楚如何进一步调试......
更新 2: 经过更多测试后,我得出结论,当满足以下所有条件时,foreverFrame 不起作用:
- 带有 IE11 的 Win 7 工作站
- 连接到远程站点(意味着不是本地主机)
- 使用 URL 中的 IP 地址连接
但是,如果以下任何一项为真,那么 foreverFrame 似乎立即起作用:
- 连接到 localhost 而不是远程服务器,或者
- 使用更新的 Windows 版本(但仍然是 IE11),或
- 使用 FQDN 而不是 IP 地址进行连接。
非常非常奇怪...我也发布到 ASP.NET 论坛、IE11 论坛和 IE11 开发者论坛,但那里没有真正的帮助。我现在决定不再深入探讨这个问题。此外,我也不会进一步调查 longPolling 问题。我刚刚编写了自己的心跳机制和连接重启处理程序......
所以这个问题仍然没有答案,但对我来说不再是一个真正的问题。
更新 3: 不幸的是,我不再有可能使用旧操作系统 Win 7 或 Win Server 2008 进行测试。此外,我已经更新到最新的 SignalR。所以这个问题仍然是一个谜,但我不再需要答案。