Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client-side disconnect gets fired when leaving page in Firefox but not in Chrome #3639

Closed
1 of 2 tasks
Tilogorn opened this issue Sep 1, 2020 · 4 comments
Closed
1 of 2 tasks
Milestone

Comments

@Tilogorn
Copy link

Tilogorn commented Sep 1, 2020

I want to:

  • report a bug
  • request a feature

Current behaviour

The socket.on('disconnect') event on the client-side gets fired, when you leave the page in Firefox. Does not happen in Chrome.

I show an error modal when the socket looses its connection because I assume the server went down (not a rare scenario on an embedded device).

Navigating different pages, each with their own var socket = io(); and socket.on('disconnect') methods leads to unwanted flickering of error modals because the browser assumes for a split second that the server went down until the new page gets loaded.

Steps to reproduce (if the current behaviour is a bug)

See my fiddle fork: https://github.com/Tilogorn/socket.io-fiddle
I just added a second page and a link to it.

Open Chrome and navigate to index.html, open the console, check option "persist logs", then click on the link. Nothing special will appear:

Bildschirmfoto vom 2020-09-01 16-00-19

Now do the same in Firefox. You will see the console.log statement of the disconnect listener.

Bildschirmfoto vom 2020-09-01 15-59-38

Expected behaviour

Silently leaving the page. Or having a possibility to detect that the user and not the server closed the connection so no need to show an error modal. reason is transport close in both ways.

Setup

  • OS: Linux Mint 19.3
  • browser: Firefox 80.0 (observed), Chrome 84 (not observable)
  • socket.io version: socket.io@2.3.0
@darrachequesne
Copy link
Member

@Tilogorn I could indeed reproduce, thanks a lot for the example.

It seems the WebSocket instance emits an onclose event when switching page in Firefox, but not in Chrome. Not sure why though...

@Tilogorn
Copy link
Author

Tilogorn commented Sep 3, 2020

I thought it's more of a timing thing. Like both browsers emit the onclose event, but Firefox does it so fast that it even triggers listeners on the "old" page (or the other way round: chrome loads the new page so fast that old listeners are not existant in RAM anymore).

Not sure if this is fixable by socket.io though... I'm sure you don't want to have code like if (firefox) { setTimeout(function() {socket.fire('disconnect')}, 200) } in your code 😉

@PorshnievN-IX
Copy link

Hello, are there any updates on this bug?

@darrachequesne
Copy link
Member

This should be fixed by socketio/engine.io-client@ed48b5d, included in socket.io-client@3.1.2.

@darrachequesne darrachequesne added this to the 3.1.2 milestone Feb 26, 2021
darrachequesne added a commit to socketio/engine.io-client that referenced this issue May 4, 2021
Since [1], the socket is now closed when receiving the "beforeunload"
event in the browser.

This change was meant to fix a discrepancy between Chrome and Firefox
when the user reloads/closes a browser tab: Firefox would close the
connection (and emit a "disconnect" event, at the Socket.IO level), but
not Chrome (see [2]).

But it also closes the connection when there is another "beforeunload"
handler, for example when the user is prompted "are you sure you want
to leave this page?".

Note: calling "stopImmediatePropagation()" was a possible workaround:

```js
window.addEventListener('beforeunload', (event) => {
  event.preventDefault();
  event.stopImmediatePropagation();
  event.returnValue = 'are you sure you want to leave this page?';
});
```

This commit adds a "closeOnBeforeunload" option, which controls whether
a handler is registered for the "beforeunload" event.

Syntax:

```js
const socket = require('engine.io-client')('ws://localhost', {
  closeOnBeforeunload: false // defaults to true
});
```

[1]: ed48b5d
[2]: socketio/socket.io#3639

Related:

- #661
- #658
- socketio/socket.io-client#1451

Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants