Context
A game shipped as a progressive web app which has timers (setTimeout
, setInterval
) and websocket connections to get real-time communication.
What is happening
Everything is fine as long as the user stays in the app. But when the user goes to another tab, or another app or turns off the screen (in case of mobile), it becomes a "hellish unknown world".
This behaviour seems to depend on browsers and platform and, maybe, even depend on the particular user behaviour. I guess browsers and OS have their own lifecycle / mechanisms to save battery and/or computation.
When the user comes back, the app is in an unknown state and I am struggling to restore the state properly.
Regarding websockets I have auto-reconnection with socket.io and reconnecting-websocket but it's not enough to solve everything.
Looking for answers
Is there a way to artificially reproduce this behaviour to be able to test solutions? It's especially hard on desktop. Websockets can't be turned off and chromium developers don't seem in a hurry to help an issue from 2014(!): websockets not included when using connection throttling
Regardless of the above, is there a pragmatic cross-browser solution to detect / solve this problem? (for example from experience, Firefox on desktop seems to behave completely different compared to Chrome, and an iPhone will disconnect far more often than an Android)
Related Links
disable the feature "Intensive throttling of Javascript timer wake ups" in Chrome or, 2. change the web-transport inactive-timeout in the client profile to more than 60 seconds. To disable the Chrome feature, key in "chrome://flags" in Chrome URL field, search for "Throttle Javascript timer" and disable the feature.
You can check if a WebSocket is disconnected by doing either of the following: Specifying a function to the WebSocket. onclose event handler property, or; Using addEventListener to listen to the close event.
By default, if a ping has not been received in 60 seconds, and the connection has been otherwise inactive, the platform will close the WebSocket. This timeout is configurable in the WS Communication Subsystem configuration, Idle Connection Timeout (sec) parameter.
Not exactly sure, but you could use service workers. As much as I know, they run in background even if your tab is not opened and get terminated if your tab closes.
Btw. lifecycles of browser tabs seem to be different on every browser, since every browser handles it different. From what I see the browser can freeze tabs if it needs more memory for other things.
Here is the docs from Chrome.
I remembered that there are some events, like onload that tell you if a user has left or reopened the tab. You could use these event to reconnect etc..
I would give different advice regarding how to design your app. From what I understand your intention is to add more logic in order to understand if the user is no longer active in the browser. This entails a different problem which is browser specifics to implement that logic. With that in mind, I would instead invest in have better error handling, both in the server and client.
Errors won't be browser-specific. Handling those will make your app more resilient and agnostic to browser changes, that could eventually change, let's say, the way they hibernate a tab, any other feature that a vendor might implement in the future.
This is an idea that you can find in services architecture, but the same pattern applies to any web-app. You might want to look for Design-for-Fail
concepts:
Complexity makes it infeasible to assume robustness on the part of the systems upon which one relies. Instead, one needs to design systems and applications at any given layer in the IT stack-based to assume the possibility of failure at lower levels. Design-for-fail necessitates thinking about fault tolerance at all layers. No longer can application developers confine themselves to thinking about functionality.
https://www.oreilly.com/library/view/designing-delivery/9781491903742/ch04.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With