I have a .NET 4.5 application based on SignalR. Server backend is written in C#, and I only have Javascript clients connecting to my hub. Currently I'm testing the latest SignalR version 2.2.2.
My application is often hosted on older Windows Server 2008 R2 and IIS 7.5, and also my users are on IE10 or IE11. This reduces available transports to foreverFrame and longPolling.
Recently we have started receiving more reports of JS clients getting disconnected. I quickly noticed that ForeverFrame doesn't work at all any more, and all JS clients are using longPolling.
This question is now specifically about ForeverFrame not working (I will post a separate question about the problems with longPolling if necessary).
Here's how I can reproduce the issue (foreverFrame transport not working):
- My application running on a Windows Server 2008 R2 & IIS 7.5 (server is regularly patched with security&critical patches only)
- Accessing my test page with IE11
- Connecting remotely (in other words not locally from the server)
- In console I see: SignalR: foreverFrame transport timed out when trying to connect."
- SignalR falls back to longPolling, and it starts OK
- On hub side I've overwritten OnConnected and OnDisconnected, and interestingly I don't see OnConnected firing, but OnDisconnected is firing
- In Developer Tools Network tab I see (Abort) for foreverFrame:
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 frame navigate 484 0 0 0 0 5335
Interestingly this issue does not happen if I connect locally. I can even use IE8 on an old server locally, and foreverFrame starts OK. Or I can use IE11 locally on my laptop and run my application on IIS Express and again all is fine. But the moment I browse to my site remotely, foreverFrame fails to start.
For what it's worth here's the code for my 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>
Here's also the full debug console output from IE11 when refreshing my test page:
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.
And here's the output from IE8 when accessing the same exact URL locally from the server itself (same results happen locally on my laptop with IE11 and 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
So.... any ideas? :)
UPDATE: I was able to test the other way around: Connecting from a Win2008R2 server, using IE8, to IIS Express on my laptop. In this scenario ForeverFrame starts completely OK. So at the moment this seems like a IE11 issue. Trying to figure out how debug this further...
UPDATE 2: After even more testing I've concluded that foreverFrame doesn't work when ALL the following are true:
- Win 7 workstation with IE11
- Connecting to remote site (meaning not localhost)
- Connecting using IP-address in URL
But immediately foreverFrame seems to work if any of the following are true:
- Connecting to localhost and not a remote server, or
- Using a later Windows version (but still IE11), or
- Connecting using FQDN instead of IP-address.
Very, very strange... I've also posted to ASP.NET forum, IE11-forum and IE11 Developer forum but no real help there. I've now decided not to go deeper into this. Also I won't be further investigating longPolling issues either. I just wrote my own heartbeat mechanism and connection restart handlers...
So this question remains unanswered, but not a real problem for me anymore.
UPDATE 3: Unfortunately I no longer have the possibility to test with older operating systems Win 7 or Win Server 2008. Also I've updated to latest SignalR. So this issue remains a mystery but I no longer need the answer.