Подтвердить что ты не робот

Как определить, когда изменяется статус онлайн/оффлайн

Я хочу знать, когда интернет-соединение потеряно и восстановлено, так что я могу переключаться между предупреждением, в котором говорится: "Крики, Интернет" и карта Google или сетка, содержащие данные, полученные на моем сервере.

Этот связанный вопрос и этот другой связанный вопрос считают, что у них есть ответ, но они не,

Их решение работает с Chrome Version 34.0.1847.137 m, MS IE v11.0.x.x, но НЕ с FireFox v29.0.1, поэтому я ищу решение, которое работает со всеми этими тремя браузерами.


[Обновление] AS @Quad указывает, что существуют различные способы определения того, что значит быть онлайн. Я определяю его как "могу ли я получить данные, которые мне нужно показать моему пользователю или нет?".


У меня есть несколько служб, которые отвечают за выборку данных с нескольких серверов (что лучше всего: единая, параметризованная, служба? Одна услуга на один сервер или одна услуга на каждый тип данных на сервер? каждая служба может затем сопоставить контроллер, который сопоставляется с представлением. Но я новичок в Angular, поэтому может быть и неправильным).

Кроме того, я закодировал службу, которая отвечает за попытку повторного подключения, когда соединение потеряно.

Любой, кто пытается выполнить $http.get и получает 404, может вызвать службу, которая будет 1) транслировать, что не было Интернета (так, чтобы никто другой не пытался подключиться)
2) регулярно пытайтесь подключиться к моему серверу и
3) при успешном завершении попыток подключения и трансляции, приложение снова подключено к сети.

Однако это казалось очень klunky, и решение, предлагаемое в двух связанных вопросах, казалось элегантным - за исключением FF:-(

Я не могу изобретать колесо здесь. Как это делают другие? На самом деле, я удивлен тем, что еще нет официального "Angular решения

4b9b3361

Ответ 1

Лучший способ, который я хотел бы знать, - перехватить обработчик HTTP, если его 401/501/и т.д., чтобы обработать его в соответствии с

Пример:

angular.module('myApp', ['myApp.services'], 
    function ($httpProvider) {

    var interceptor = ['$rootScope', '$q', function ($rootScope, $q) {

        function success(response) {
            return response;
        }

        function error(response) {
            var status = response.status; // error code

            if ((status >= 400) && (status < 500)) {
                $rootScope.broadcast("AuthError", status);
                return;
            }

            if ( (status >= 500) && (status < 600) ) {
                $rootScope.broadcast("ServerError", status);
                return;
            }

            // otherwise
            return $q.reject(response);

        }

        return function (promise) {
            return promise.then(success, error);
        }

    }];
    $httpProvider.responseInterceptors.push(interceptor);

то в вашем коде, который прослушивает on, просто добавьте

$rootScope.$on("ServerError", someServerErrorFunction);

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

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

Ответ 2

В моих приложениях у меня есть конечная точка /ping, которую я опросу каждые X секунд. Это, конечно, не подходит для крупномасштабных приложений.

angular.module("pingMod", [])
    .run(function ($http, $interval) {
        var TIME = 60000;
        function ping() {
            $http.get("/ping");
        }
        $interval(ping, TIME);
    });

Я использую это в сочетании с тем, что предложил @Gil, HTTP-перехватчик. Когда мы получаем статус 0, мы в автономном режиме. Это срабатывает для любого вызова AJAX, который использует $http.

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

angular.module("myModule", [])
    .config(function ($httpProvider) {
    var interceptor = [
        '$q',
    function ($q) {
        return function (promise) {
            return promise.then(function (response) {
                return response;
            }, function (response) {
                if (response.status === 0) {
                    // We're offline!
                }
                return $q.reject(response);
            });
        };
    }];
    $httpProvider.responseInterceptors.push(interceptor);
})

Ответ 3

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

Элегантный способ реализовать это в angular - контролировать всю сетевую активность с помощью $http, инъекционной службы, через которую все XHR потоки деятельности. Restangular предлагает вам:

  • RestangularProvider.addFullRequestInterceptor: дает вам полный доступ к запросу перед отправкой каких-либо данных на сервер.

  • RestangularProvider.setErrorInterceptor: вызывается после каждого ответа об ошибке с сервера.

Вот псевдокод для реализации наблюдателя статуса с использованием Restangular:

var last_request

RestangularProvider.addFullRequestInterceptor:
  last_request = Save last request

RestangularProvider.setErrorInterceptor:
    - Display the 'offline' status message to user
    - Use $interval to periodically re-submit last_request until successful
    - When periodic re-submission succeeds, hide 'offline' status message

Даже если вы специально не просили ответа, используя Restangular, вы сказали, что искали нужный шаблон, и у Restangular есть очень простые в использовании, но мощные шаблоны. Конечно, одна и та же идея, представленная здесь, может быть реализована только с помощью $http.