What is the most reliable event to listen for when window is closed

Viewed 104

I am building an online game, and one feature involves being able to put up a game request on the site so that other users can see it, and maybe accept it. For this site, I want to remove the game request of a user when they close the page, by either navigating to another page on the site, closing it altogether, following a link, etc. so that other users who are still online don't respond to a dead request.

The issue is, I was planning on writing code to do that and put it in an event listener that listens for the closing of the page, but apparently, some of the events have issues with them, according to MDN:

  • Unload/beforeunload: This event apparently does not fire reliably on mobile, especially when the user opens another app without closing the browser, and closes the browser with the app manager afterward. I imagine this could lead to problems on the phone, but this is my default option for now.
  • Visibility: MDN's suggested alternative to unload, the change in visibility event would fire when a mobile user opens another app, but it also fires when they open another tab in the browser. This would mean they would have to sit there looking at the lobby page until someone accepted their game request, which is not ideal.
  • Disconnection: Another thing I was thinking about was listening to the disconnection event fired by a socket (I am using socket.io to manage user connections) but I imagine that a disconnection due to a bad network can also fire this event, even if it is momentary. A user would then have to remake their request; also not ideal.

These are my main 3 options for now, and my question is: Is there an event that fires when a page is closed that I can listen to, that works like unload but also accounts for mobile users' issues as mentioned above? Or maybe something like the visibility change, but does not fire when they go to another tab? Or something else entirely that sidesteps both of these issues.

3 Answers

Use window.onbeforeunload. This allows you to do a few actions before the window either refreshes or is closed. For instance, you could store something to localStorage or a cookie to store that something happened. The reason why this maybe hasn't been reliable is because your script has to be quick. You only have a certain amount of time before the page unloads. Here is an example of something you could do.

window.onbeforeunload = function() {
    document.cookie = 'goodbye=true';
}

Then you could check for this cookie when the page loads. If your page is on mobile, the browser may do nothing when a cookie is set or something is set to localStorage because of privacy measure. This simply is how it is.

You could use a combination of the different options. Assuming you can reliably detect whether they are on mobile or not. If they are on mobile, use the visibility event. If they are on desktop, use the unload event.

Another option is on the visibility change you could send a "I might be disconnecting" message and then use a setTimeout() to send a follow up message 5 seconds later saying "never mind!" Then on the server side you could set a "disconnect timeout" that waits 10 seconds for the "never mind!" message. If it doesn't receive it within 10 seconds, then drop the user and assume they disconnected.

I would use beforeunload but also prepare for the unreliability. When it works, it removes the request like you describe. Then also make it up so when a user responds to the game request, it pings back to the original user. If the ping fails, say something like "oops they left." If the ping goes through, query the original user "you got a response. do you still want to play?"

Related