简体   繁体   中英

Node.js - Recreating navigator.onLine

I have a Node.js app. I am trying to write a utility app to do some network detection. I'm creating this app just to learn more about Node.

In this app, I want to see if a) my computer is online and b) if it can reach the internet. If I was doing this in the browser, I could use navigator.onLine , then attempt to reach a website. However, that's not an option in Node.

I looked at the OS module's networkInterfaces method , however, that doesn't seem to have what I need. For example, if you go to a Starbucks, you can be "online" but not actually reach the internet until you agree to the terms of service for their network. I've been testing this scenario by toggling airplane mode on my machine. Whether Airplane Mode is on or off, the networkInterfaces method returns the same thing.

How can I recreate the navigator.onLine functionality in Node?

Here is the code to check whether the internet is available or not.

For this install the is-online module: npm i is-online

 index.js: const isOnline = require('is-online'); isOnline({ timeout: 1000 }).then(online =>{ if(online) console.log('Internet is available') else console.log('Internet is not available') })

By calling onConnected and passing the call back function which will be called when the connection is established

const dns = require('dns');

function onConnected(callback){
    dns.resolve('www.google.com', function(err) {
        if (!err) callback();
    });
}

You can define navigator variable globally and set onLine param true or false.

const dns = require('dns');
const navigator = global.navigator = {onLine: false};

((navigator) => {
  const dns = require('dns');
  setInterval(() => {
    dns.resolve('www.google.com', 
                error => navigator.onLine = !error);
  }, 1000);
})(navigator);


setInterval(() => {
  console.log('Is online:', navigator.onLine ? 'yes' : 'no');
}, 1500);

I'd go the route of

var exec = require('child_process').exec, child;
child = exec('ping -c 1 8.8.8.8', function(error, stdout, stderr){
     if(error !== null)
          console.log("Not available")
      else
          console.log("Available")
});

or trying to dns lookup

require('dns').lookupService('8.8.8.8', 53, function(err, hostname, service){
  console.log(hostname, service);
    // google-public-dns-a.google.com domain
});

Maybe trying to resolve a domain name

function checkNameResolution(cb) {
    require('dns').lookup('google.com',function(err) {
        if (err && err.code == "ENOTFOUND") {
            cb(false);
        } else {
            cb(true);
        }
    })
}

Really depends on your use case. Personally i'd spring for dnslookup of a higly avaliable address. But if your behind some sort of dns mask that resolves domains do localhost it might not be effective, which would in turn add the need to test name resolution also/instead. Combine those in a function like checkInternetConnection() and you'll be as good as it gets.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM