Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Events for network status change in Node.js?

All the solutions I've found simply poll a service. E.g. they ping google.com every second to see if the Node service has Internet access.

However, I'm looking for a cleaner event-based solution. In the browser, there's window.ononline and window.onoffline. I know these aren't perfect, but they're still better than nothing.

I'm not necessarily looking for a way to see if a Node service is online, I'm just looking for a way to see if the OS thinks it's online. E.g. if the OS isn't connected to any network interfaces, then it's definitely offline. However, if it's connected to a router, then I can maybe ping google.com.

like image 532
Leo Jiang Avatar asked Jan 05 '19 19:01

Leo Jiang


2 Answers

I believe currently, that is the most effective way to tell if you're connected.

If you'd like to have an "event-based" solution, you can wrap the polling service with something like this:

connectivity-checker.js

const isOnline = require("is-online");

function ConnectivityChecker (callback, interval) {
    this.status = false;
    this.callback = callback;
    this.interval = this.interval;
    // Determines if the check should check on the next interval
    this.shouldCheckOnNextInterval = true;
}

ConnectivityChecker.prototype.init = function () {
    this.cleanUp();

    this.timer = setInterval(function () {
        if (this.shouldCheck) {
            isOnline().then(function (status) {
                if (this.status !== status) {
                    this.status = status;
                    this.callback(status);
                    this.shouldCheckOnNextInterval = true;
                }
            }).catch(err => {
                console.error(err);
                this.shouldCheckOnNextInterval = true;
            })

            // Disable 'shouldCheckOnNextInterval' if current check has not resolved within the interval time
            this.shouldCheckOnNextInterval = false;
        }
    }, this.interval);
}

ConnectivityChecker.prototype.cleanUp = function () {
    if (this.timer) clearInterval(this.timer);
}

export { ConnectivityChecker };

Then in your site of usage (E.g. app.js)

app.js

const { ConnectivityChecker } = require("/path/to/connectivity-checker.js");

const checker = new ConnectivityChecker(function(isOnline) {
    // Will be called ONLY IF isOnline changes from 'false' to 'true' or from 'true' to 'false'.
    // Will be not called anytime isOnline status remains the same from between each check
    // This simulates the event-based nature you're looking for


    if (isOnline) {
        // Do stuff if online
    } else  {
        // Do stuff if offline
    }
}, 5000);

// Where your app starts, call
checker.init();

// Where your app ends, call
// checker.cleanUp();

Hope this helps...

like image 62
Kwame Opare Asiedu Avatar answered Sep 28 '22 05:09

Kwame Opare Asiedu


Your assumption is partly correct. From OS level, you can detect whether you are connected to a network or not, but that does not guarantee that you have access to internet. Also, checking natively whether I have network connectivity is going to be different for different OSs.

So, the most reliable way to understand whether you have Internet connectivity is to try accessing any resource from the internet, and see if you are successful. The resource might be non-accessible for some reasons, so your strategy should be accessing multiple well-known resources and see if you can access any of them.

For that, I have used the is-online npm package. It relies on accessing internet resources and DNS resolution to check whether you are connected to internet.

Example code:

const isOnline = require('is-online');

isOnline().then(online => {
  if(online){
     console.log("Connected to internet");
  }else{
     console.log("Not connected to internet");
  }
 });
like image 30
WaughWaugh Avatar answered Sep 28 '22 04:09

WaughWaugh