Reputation: 51
We are facing this issues with our app, only in safari browser, especially on iOS devices.
Not sure if this is a known issue (I tried searching but found nothing). Safari for Mac appears to be silently dropping web socket connections due to inactivity/idle if the page/tab is not in focus. The biggest issue is that in mobile iOS X is very persistent.
Open Safari > Website loads > Put Safari in Idle and open any application or lock the device. On wake up, Safari is closing the connection and the data is not displayed anymore, we get infinite loading of the modules where we request the data.
Expected behavior Websockets should be kept alive via the heartbeat functionality. Not seeing this behavior in other browsers so unlikely to be the code.
import 'whatwg-fetch';
import Config from "../config/main";
import WS from "./websocket";
import Helpers from "./helperFunctions";
var Zergling = (function (WS, Config) {
'use strict';
var Zergling = {};
var subscriptions = {}, useWebSocket = false, sessionRequestIsInProgress = false, loginInProgress = false,
uiLogggedIn = false, // uiLogggedIn is the login state displayed in UI (sometimes it differs from real one, see delayedLogoutIfNotRestored func)
authData, session, connectionAvailable, isLoggedIn, longPollUrl;
Zergling.loginStates = {
LOGGED_OUT: 0,
LOGGED_IN: 1,
IN_PROGRESS: 2
};
Zergling.codes = { // Swarm response codes
OK: 0,
SESSION_LOST: 5,
NEED_TO_LOGIN: 12
};
function getLanguageCode (lng) {
if (Config.swarm.languageMap && Config.swarm.languageMap[lng]) {
return Config.swarm.languageMap[lng];
}
return lng;
}
//helper func for fetch
function checkStatus (response) {
if (response.status >= 200 && response.status < 300) {
return response;
} else {
var error = new Error(response.statusText);
error.response = response;
throw error;
}
}
//helper func for fetch
function parseJSON (response) {
return response.json();
}
/**
* @description returns randomly selected(taking weight into consideration) long poll url
* @returns {String} long polling URL
*/
function getLongPollUrl () {
if (!longPollUrl) {
longPollUrl = Helpers.getWeightedRandom(Config.swarm.url).url;
console.debug('long Polling URL selected:', longPollUrl);
}
return longPollUrl;
}
/**
* @description
* Applies the diff on object
* properties having null values in diff are removed from object, others' values are replaced.
*
* Also checks the 'price' field for changes and adds new field 'price_change' as sibling
* which indicates the change direction (1 - up, -1 down, null - unchanged)
*
* @param {Object} current current object
* @param {Object} diff received diff
*/
function destructivelyUpdateObject (current, diff) {
if (current === undefined || !(current instanceof Object)) {
throw new Error('wrong call');
}
for (var key in diff) {
if (!diff.hasOwnProperty(key)) continue;
var val = diff[key];
if (val === null) {
delete current[key];
} else if (typeof val !== 'object') {
current[key] = val;
} else { // diff[key] is Object
if (typeof current[key] !== 'object' || current[key] === null) {
current[key] = val;
} else {
var hasPrice = (current[key].price !== undefined);
var oldPrice;
if (hasPrice) {
oldPrice = current[key].price;
}
destructivelyUpdateObject(current[key], val);
if (hasPrice) {
current[key].price_change = (val.price === oldPrice) ? null : (oldPrice < val.price) * 2 - 1;
}
}
}
}
}
Upvotes: 5
Views: 3612
Reputation: 19221
This is and iOS feature that protects users against code draining their battery...
Push notifications for background applications should be performed using iOS's push notification system rather than by keeping an open connection alive.
There are hacks around this limitation, but the truth is that the limitation is good for the users and shouldn't be circumvented.
Read the technical note in the link for more details.
Upvotes: 2