Как определить, когда изменяется статус онлайн/оффлайн
Я хочу знать, когда интернет-соединение потеряно и восстановлено, так что я могу переключаться между предупреждением, в котором говорится: "Крики, Интернет" и карта 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 решения
Ответы
Ответ 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
.