question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Prevent socket io from emitting ping timeout for inactive or not focused browser page in mobile browsers chrome, firefox and safari.

See original GitHub issue

You want to:

  • report a bug

Current behaviour

What is actually happening?

I have a simple chat app using socket io. Very similar to the socket io chat official demo. Socket io goes to ping timeout on all mobile browsers whenever the user minimizes the page or opens another app or page gets out of foucs.

In my web app whenever, the user clicks on file input upload from their chrome/firefox/safari browser on mobile, it opens up the phone dialog box to select the file from galley to select and upload. During this time (my chat page gets out of focus due to visibility), when user is searching for a file, and after exact 30 seconds, socket io client issues ping timeout, and the person chat is disconnected.

In my application level, i am doing a reconnect if socket io goes to ping timeout for whatever reason, but that doesn’t fix my problem, because if the user clicks on 1 file after 31 seconds, then that image file is not sent in chat, because socket io was timed out during that time, and it takes few seconds to reconnect, when the user’s focus is back on the browser tab. So the file upload action is lost, because file is uploaded but socket io connection was on ping timeout. so when it reconnects, the selected file upload is never sent to the other connected user.

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

Please check relevant stackoverflow question: https://stackoverflow.com/questions/58667207/prevent-socket-io-from-ping-timeout-on-inactive-or-not-focused-browser-page-on-c

Expected behaviour

Whenever on mobile or desktop browsers, if a user navigates away from socket io chat page and comes back, socket io should still keep the client connected, and should not issue a ping timeout event and cause disconnect after 30 seconds. It should keep chat active no matter how long a person is out of focus of the page.

What is expected?

Setup

  • OS: Android and iOS
  • browser: happening on safari, firefox, chrome (android and iphones)
  • socket.io version: 2.2.0 (same issue happening on 2.3.0 too, i tried upgrading my client and socket io both)

Other information (e.g. stacktraces, related issues, suggestions how to fix)

I tried detecting whenever user’s page focus is out, using this code,

document.addEventListener(“visibilitychange”, onchange); from Is there a way to detect if a browser window is not currently active?

and then once page is not in focus, i used setinterval to emit my custom heartbeat event to my server code. (just to keep socket io from talking to server to keep connection alive)… This works fine for desktop browsers, But on all mobile browsers, whenever user’s page is not in focus, i.e if a user minimizes the browser, opens a new app, or goto select file upload screen, socket io times out after 30 seconds or sometimes even faster then this.

My client js code:

`var beating; //function to detect if user gone out of page

//startSimulation and pauseSimulation defined elsewhere function handleVisibilityChange() { //socket = this.socket; if (document.hidden) { // console.log(); $(‘#logwrapper’).prepend(" üser is outside \n ", socket.id);

//emit on server after every 10 seconds
beating = setInterval(function () {
  $('#logwrapper').prepend(" inside interval emitting");

  socket.emit('heartbeat', { data: "a" });
}, 15000)

} else { //console.log(“üser is in”); $(‘#logwrapper’).prepend(" üser is in \n ", socket.id); console.log(“çlearing inteval beating from visiblity”); clearInterval(beating); } }

document.addEventListener(“visibilitychange”, handleVisibilityChange, false);`

And my server.js code

//socket events for heartbeat socket.on("heartbeat", function (data) { console.log("socket is outside ", data, socket.id); }); //socket events for heartbeat , just log it so that my client remains active and keep communicating with server, to avoid socket io timeout I also tried adjusting my socket io server & client timeout configs, but that is not making any difference, after user minimise the browser page on mobile, chorme, firefox & safari, socket io client emits ping timeout after 30 seconds or so,

How can i increase this timeout, so socket io connection remains active (don’t ping timeout) for longer time (as much as i want)?

Here are my server.js configs for socket io:

var io = require("socket.io")( 231, { transports: ["websocket", "polling"] }, server, { path: '/socket.io', serveClient: true, // below are engine.IO options pingInterval: 25000, //was 10k, how many ms before sending a new ping packet, => how often to send a ping pingTimeout: 30000, //should be above 30k to fix disconnection issue how many ms without a pong packet to consider the connection closed upgradeTimeout: 20000, // default value is 10000ms, try changing it to 20k or more agent: false, cookie: false, rejectUnauthorized: false, reconnectionDelay: 1000, reconnectionDelayMax: 5000, maxHttpBufferSize: 100000000 //100 mb } ); and my socket io client configs:

this.socket = io.connect('https://appurl.com', { reconnection: true, reconnectionDelay: 1000, reconnectionDelayMax: 5000, reconnectionAttempts: Infinity, //our site options transports: ["polling", "websocket"], secure: true, rejectUnauthorized: false, forceNew: false, timeout: 60000 }); Basically on all mobile browsers, as long as page gets out of focus, my JS code stops executing, and whenever the page focused again, JS exection resumes, looks like its not a problem with setinterval or settimeout. How can i keep executing my client JS code to keep socket io from doing ping timeout?

I also tried a similar logic using settimeout, https://codepen.io/Suhoij/pen/jAxtn

this code works in codepen on all mobile browsers, even if i minimise this page on my mobile and come back again, the timer is still executing, but the same code when i run on my app, it doesn’t work in my code. Why? Is socket io pausing my all client.js code when page is not in focus? OR is my logic not correct? I also tried emitting an event from my server.js after every 2 second to all clients, but the emits stop when page is not in foucs on mobile 😕

Relevant socket io issues: https://github.com/socketio/socket.io/issues/2769

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
Twoiscommented, Nov 5, 2019

I guess this issue is not socket.io related issue, because on mobile the apps has limitations like they are closed or paused after 30 second. Until the browser not request background permission from the user, they will be closed and any js code will stop work.

I solved the same issue, I use socket.io with angular and I wrote a wrapper service around socket.io. I wrote a queue system, so when my client want to send message to the server (it could be text or file, whatever), first I store the message in an array with Id, and I listen to connection changes, and when the connection reestablished I send the messages from the queue. Of course I use IDs to identify the messages, to remove from the queue when the server received them, and prevent to send the message more times.

0reactions
darrachequesnecommented, Nov 24, 2021

For future readers:

This should be fixed in latest versions, due to:

Which means the Socket.IO client does not rely on timers which can be throttled for tabs put in background.

Please reopen if needed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Prevent Socket IO from ping timeout on inactive or not focused ...
This works fine for desktop browsers, But on all mobile browsers, whenever user's page is not in focus, i.e if a user minimizes...
Read more >
Prevent Socket connection from initializing again-node.js
generate video file from binary data collected from socket connection · Prevent Socket IO from ping timeout on inactive or not focused browser...
Read more >
Troubleshooting connection issues | Socket.IO
When a browser tab is not in focus, some browsers (like Chrome) throttle JavaScript timers, which could lead to a disconnection by ping...
Read more >
Safari Technology Preview Release Notes - Apple Developer
Note: Shared Tab Groups and syncing for Tab Groups, Website Settings, and Web Extensions are not enabled in this release. Web Inspector. Elements...
Read more >
Changelog - Cypress Documentation
Fixed a regression introduced in the Electron browser in Cypress 10.8.0 where ... not handled within cy.origin for requests other than the AUT...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found