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

Disconnect after 5 minutes if tab minimized on Chromium #4040

Closed
SkyLionx opened this issue Aug 5, 2021 · 5 comments
Closed

Disconnect after 5 minutes if tab minimized on Chromium #4040

SkyLionx opened this issue Aug 5, 2021 · 5 comments
Labels
bug Something isn't working
Milestone

Comments

@SkyLionx
Copy link

SkyLionx commented Aug 5, 2021

Describe the bug
Using a Chromium browser, when the tab through which the connection is established is minimized for more than 5 minutes, the client gets disconnected by the server due to a ping timeout.

To Reproduce

Socket.IO server version: 4.1.3

Server

const http = require("http");
const httpServer = http.createServer();
const io = require("socket.io")(httpServer, {
	cors: {
		origin: "*",
		methods: ["GET", "POST"],
	},
});

io.on("connection", (socket) => {
	console.log("connected");

	socket.on("disconnect", () => {
		console.log("disconnected");
	});

	socket.on("message", (message) => {
		console.log(new Date().toLocaleTimeString(), "Received:", message);
	});
});

httpServer.listen(3000, () => {
	console.log("listening on *:3000");
});

Socket.IO client version: 4.0.1

Client

const socket = io("ws://localhost:3000", {transports: ["websocket", "polling"]});

setInterval(() => {
        const now = new Date().toLocaleTimeString();
        socket.send(now);
}, 5000);

Server log:

listening on *:3000
connected
11:06:25 Received: 11:06:25
11:06:30 Received: 11:06:30
11:06:35 Received: 11:06:35
11:06:40 Received: 11:06:40
11:06:45 Received: 11:06:45
11:06:50 Received: 11:06:50
11:06:55 Received: 11:06:55
11:07:00 Received: 11:07:00
11:07:05 Received: 11:07:05
11:07:10 Received: 11:07:10
11:07:15 Received: 11:07:15
11:07:20 Received: 11:07:20
11:07:25 Received: 11:07:25
11:07:30 Received: 11:07:30
11:07:35 Received: 11:07:35
11:07:40 Received: 11:07:40
11:07:45 Received: 11:07:45
11:07:50 Received: 11:07:50
11:07:55 Received: 11:07:55
11:08:00 Received: 11:08:00
11:08:05 Received: 11:08:05
11:08:10 Received: 11:08:10
11:08:15 Received: 11:08:15
11:08:20 Received: 11:08:20
11:08:25 Received: 11:08:25
11:08:30 Received: 11:08:30
11:08:35 Received: 11:08:35
11:08:40 Received: 11:08:40
11:08:45 Received: 11:08:45
11:08:50 Received: 11:08:50
11:08:55 Received: 11:08:55
11:09:00 Received: 11:09:00
11:09:05 Received: 11:09:05
11:09:10 Received: 11:09:10
11:09:15 Received: 11:09:15
11:09:20 Received: 11:09:20
11:09:25 Received: 11:09:25
11:09:30 Received: 11:09:30
11:09:35 Received: 11:09:35
11:09:40 Received: 11:09:40
11:09:45 Received: 11:09:45
11:09:50 Received: 11:09:50
11:09:55 Received: 11:09:55
11:10:00 Received: 11:10:00
11:10:05 Received: 11:10:05
11:10:10 Received: 11:10:10
11:10:15 Received: 11:10:15
11:10:20 Received: 11:10:20
11:10:25 Received: 11:10:25
11:10:30 Received: 11:10:30
11:10:35 Received: 11:10:35
11:10:40 Received: 11:10:40
11:10:45 Received: 11:10:45
11:10:50 Received: 11:10:50
11:10:55 Received: 11:10:55
11:11:00 Received: 11:11:00
11:11:05 Received: 11:11:05
11:11:10 Received: 11:11:10
11:11:15 Received: 11:11:15
11:11:20 Received: 11:11:20
11:11:32 Received: 11:11:32
disconnected

Expected behavior
The server should keep receiving messages after 5 minutes even if the tab is minimized. Since browsers do some battery optimization, it is possible that the messages don't arrive at the correct interval, but the connection should still be kept open.

Platform:

  • Device: Desktop PC
  • OS: Windows 10

Additional context
In this case the problem is that the server default pingTimeout is not high enough to be able to correctly receive a pong response from the client if it has been minimized for more than 5 minutes, probably due to Chrome Intensive Throttling.
If I try to increase the pingTimeout interval from the server, I am able to keep the connection opened. By doing some experiments I found out that I can set it as low as 44 seconds for the client to be able to reply to the ping message.
Even if this is an expected behavior, shouldn't the default interval be higher? In any case the problem can be solved by setting it to 60000.

@SkyLionx SkyLionx added the bug Something isn't working label Aug 5, 2021
@darrachequesne
Copy link
Member

Thanks for the detailed issue and the link 👍

The problem with increasing the default value of pingTimeout is that React Native will complain if a timer is created with a delay that is bigger than 60 seconds: facebook/react-native#12981

(currently the timer is set to 45 seconds, as pingInterval defaults to 20000 and pingTimeout defaults to 25000)

That being said, if the browser decides to close the connection to save the battery, I'm not sure we should intervene. What do you think?

@GingerAdonis
Copy link

GingerAdonis commented Aug 11, 2021

That being said, if the browser decides to close the connection to save the battery, I'm not sure we should intervene. What do you think?

If I read it correctly the websocket connection should stay open, even if battery saving is active. It's just the ping timeout which closes the websocket connection. I'd say that this is a minor problem on socket.io's side.

@SkyLionx
Copy link
Author

I tried to reproduce the same behavior with plain Web Sockets and the connection is still kept open even if the tab is throttled, so I think that as @GingerAdonis says is just a matter of the ping timeout. I'm not completely sure if something has to be changed in the library, maybe adding just a note in the Disconnection detection section of the documentation may be enough for other users thay may experience this problem, and then each one can adjust the ping timeout depending on the application.

@Madriix
Copy link

Madriix commented Aug 28, 2021

I managed to solve a problem that did not exist on socket.io 2.x, it was to set this parameter https://socket.io/docs/v4/client-initialization/#closeOnBeforeunload to false
It should be noted here: https://socket.io/docs/v4/how-it-works/#Disconnection-detection

Here is how to reproduce the problem (this was done in production mode and not on a test version):

  1. The html page contains this: this.socket = io(server);

  2. The html page also contains this in jquery:
    $(window).on("beforeunload", function() { return 'Are you sure you want to leave?'; });

  3. Start your browser-side application and connect to socket.io

  4. Then click on the red cross of the browser to try to close it, it will not close because you refused to close the page, however watch the socket disconnect as soon as you try to close the page but you refused close it via the dialog box It closes anyway, by displaying "ping timeout" after one minute maximum. Just put this and the problem is solved:
    this.socket = io(server, { closeOnBeforeunload: false });

Now I have a second problem that I still can't solve, but which works fine on socket.io 2.x: as a new user, occasionally it refuses to connect to the socket, there is no error however. You just have to refresh the page and then it's good to start.
This is quite penalizing for the UX because not every person will try a second time.
Also I don't know if the problem is with socket.io 4.x or the update of an npm package, or because of the evolution of browsers (new versions) or the update of my code on the client side or server side (in nodejs). However it could look like a socket.io version 4 problem, there is surely an option to put but I do not know which one.

@darrachequesne
Copy link
Member

For future readers: this should be fixed by socketio/engine.io-client@f30a10b, included in socket.io-client@4.1.3.

I've added a note in the troubleshooting guide: https://socket.io/docs/v4/troubleshooting-connection-issues/#the-browser-tab-was-minimized-and-heartbeat-has-failed

@darrachequesne darrachequesne added this to the 4.1.3 milestone Nov 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants