Safari разрывает соединение с веб-сокетом из-за простоя / неактивности, когда страница не в фокусе - PullRequest
0 голосов
/ 16 ноября 2018

Мы сталкиваемся с этими проблемами в нашем приложении, только в браузере Safari, особенно на устройствах iOS.

Текущее поведение

Не уверен, что это известная проблема (я пытался найти, но ничего не нашел). Safari для Mac, по-видимому, молча прерывает соединения через веб-сокет из-за неактивности / простоя, если страница / вкладка не в фокусе. Самая большая проблема в том, что в мобильном iOS X очень устойчивый.

Шаги для воспроизведения

Откройте Safari> Загрузка веб-сайтов> Переведите Safari в режим ожидания и откройте любое приложение или заблокируйте устройство. При пробуждении Safari закрывает соединение, и данные больше не отображаются, мы получаем бесконечную загрузку модулей, где мы запрашиваем данные.

Ожидаемое поведение Веб-сокеты должны поддерживаться с помощью функции сердцебиения. Не видеть такого поведения в других браузерах, поэтому вряд ли это будет код.

Возможно, это какая-то функция энергосбережения, которая переопределяет / игнорирует сердцебиения?

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;
                    }
                }
            }
        }
    }

1 Ответ

0 голосов
/ 17 ноября 2018

Это и функция iOS, которая защищает пользователей от разрядки кода их батареи. ...

Push-уведомления для фоновых приложений должны выполняться с использованием системы push-уведомлений iOS, а не с открытымсоединение живое.

Существуют хаки, связанные с этим ограничением, но правда в том, что ограничение хорошо для пользователей и не должно быть обойдено.

Чтение Техническое примечание вссылка для более подробной информации.

...