How to detect when online/offline status changes

前端 未结 3 1872
慢半拍i
慢半拍i 2020-12-23 02:11

I want to know when internet connection is lost and regained, so that I can toggle between an alert saying \"whoops, no internet\" and a Google map or a grid containing data

相关标签:
3条回答
  • 2020-12-23 02:17

    In my applications, I have a /ping endpoint that I poll every X seconds. This of course may not be suitable for large-scale apps.

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

    I use this in combination with what @Gil suggested, an HTTP interceptor. When we get a 0 status, we are offline. This is triggered for any AJAX call that uses $http.

    Here is code for the interceptor using $http. You may of course decide you want to use Restangular instead, but it depends on your app needs.

    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);
    })
    
    0 讨论(0)
  • 2020-12-23 02:23

    The best way that I would know would be to intercept the HTTP handler, if its a 401 / 501/ etc then to handle it according

    ex:

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

    then in your code that listens for the on of, just add in

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

    You could also add an internal flag and broadcast only when that flag changed.

    But if you are looking for a solution where the user is not communicating with the server too frequently, you could add a section that pings the server every minute or so, but that may not be responsive as you like.

    0 讨论(0)
  • 2020-12-23 02:25

    You can detect disconnect either by polling your server, or just waiting for a failed response. The latter approach is preferable unless you have special requirements. Once a disconnect is detected, you will need to use polling to detect re-connection.

    An elegant way to implement this in angular is to monitor all network activity with $http, the injectable service through which all XHR activity flows. Restangular abstracts this out for you with:

    • RestangularProvider.addFullRequestInterceptor: Gives you full access to the request before sending any data to the server.

    • RestangularProvider.setErrorInterceptor: Called after each error response from the server.

    Here is the pseudo-code to implement a status watcher using 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
    

    Even though you didn't specifically ask for an answer utilizing Restangular, you did say you were looking for an established pattern and Restangular has some very easy-to-use yet powerful patterns built-in. Of course the same idea presented here could instead be implemented with just $http.

    0 讨论(0)
提交回复
热议问题