We have an ASP.Net WebForms application that uses SignalR (v2.4.1) to do some bi-directional communications between server and client. It's worked fine for years: connections are stable, hundreds of users use it, etc.
However, we've started to get sporadic reports of connection problems from across our client base, all reporting the same thing: if the browser (Chrome) session goes idle for more than 5 minutes, the connection drops in the background. All timers in the page stop being run regularly, which (amongst other things) stops "keepalives" stop being sent, and eventually the connection fails with the client-side error:
The client has been inactive since <date> and it has exceeded the inactivity timeout of 50000 ms. Stopping the connection.
Standard procedure after this would be to automatically restart the connection, but this doesn't do anything. If/when the user reactivates the page (e.g. by switching to the tab), everything starts to spring back into life, albeit with a closed SignalR connection.
After much investigation, it seems that we're being impacted by this change introduced in Chrome v88, where timers (setTimeout
s) are severely restricted if
- The page has been hidden for more than 5 minutes
- The timer has been "chained" 5 or more times - I'm assuming this is similar to recursion, where the timer calls itself.
- Page has been "silent" for 30 seconds
The 5 minutes/30 seconds condition fits with the reports we're getting. However, we're running pretty basic Javascript on our page: there are only two uses of setTimeout
in our own code, neither of which could ever "chain" (recurse) onto themselves. We also cannot replicate the issue: it's happened to us in testing, but we can't make it happen reliably. Disabling this feature via chrome://flags/#intensive-wake-up-throttling
seems to mitigate the issue - but of course, we can't make this a requirement to use our site.
The only other Javascript running on the site is jquery.signalR-2.4.1.js
, and from the SignalR source, there are lots of setTimeout
s in there. Could SignalR be impacted by this change in Chrome; perhaps when it tries to silently reconnect after a temporary network issue or some other unpredictable event?
If not, is there any way, in any browser or IDE, to track which timers have been launched (and, more importantly, "chained"), so we can see what could be triggering this restriction?
See Question&Answers more detail:
os