Donald Derek
Donald Derek

Reputation: 2597

Check for internet connectivity in NodeJs

Installed NodeJS on Raspberry Pi, is there a way to check if the rPi is connected to the internet via NodeJs ?

Upvotes: 52

Views: 72031

Answers (12)

AllanRibas
AllanRibas

Reputation: 1184

I do it like this

async function fetchInternet(){
  return new Promise(async (resolve, reject) => {
  await fetch(`https://www.google.com`,  {
        method: 'GET',
        cache: "no-cache",
        referrerPolicy: "no-referrer",
      })
      .then(data => {  resolve(data["status"] == 200)} )
      .catch(error => { resolve(!error == null) })
  })    
}

fetchInternet().then(data => { console.log("hasInternet", data) })

Upvotes: 0

async function checkInternet() {
  const address = 'www.google.com';
  const config = {
    timeout: 100,
  };
  const probeAsync = (address) => {
    return new Promise((resolve) => {
      ping.sys.probe(address, (isAlive) => {
        resolve(isAlive);
      }, config);
    });
  };
  const isAlive = await probeAsync(address);


  return isAlive
}

ping module requires for this function

Upvotes: 0

Chukwuemeka Maduekwe
Chukwuemeka Maduekwe

Reputation: 8586

It's a very simple function that does not import any stuff, but makes use of JS inbuilt function, and can only be executed when called, it does not monitor loss/internet connection; unlike some answers that make use of cache, this result is accurate as it does not return cached result.

const connected = fetch("https://google.com", {
    method: "FET",
    cache: "no-cache",
    headers: { "Content-Type": "application/json" },
    referrerPolicy: "no-referrer",
}).then(() => true)
  .catch(() => false);

call it using await(make sure your'e inside an async function or you'll get a promise)

console.log(await connected);

Upvotes: 1

chickens
chickens

Reputation: 22354

Here is a one liner: (Node 10.6+)

let isConnected = !!await require('dns').promises.resolve('google.com').catch(()=>{});

Upvotes: 7

Javad
Javad

Reputation: 437

Since I was concerned with DNS cache in other solutions here, I tried an actual connectivity test using http2. I think this is the best way to test the internet connection as it doesn't send much data and also doesn't rely on DNS resolving alone and it is quite fast.

Note that this was added in: v8.4.0

const http2 = require('http2');

function isConnected() {
  return new Promise((resolve) => {
    const client = http2.connect('https://www.google.com');
    client.on('connect', () => {
      resolve(true);
      client.destroy();
    });
    client.on('error', () => {
      resolve(false);
      client.destroy();
    });
  });
};

isConnected().then(console.log);

Edit: I made this into a package if anyone is interested.

Upvotes: 6

Nagnath Mungade
Nagnath Mungade

Reputation: 1009

It is very helpful to check internet connection for our browser is available or not.

var internetAvailable = require("internet-available");

internetAvailable().then(function(){
    console.log("Internet available",internetAvailable);
}).catch(function(){
    console.log("No internet");
});

for more[internet-available][1]: https://www.npmjs.com/package/internet-available

Upvotes: 1

Roman Frolov
Roman Frolov

Reputation: 1008

As of 2019 you can use DNS promises lookup.

NOTE This API is experimental.

const dns = require('dns').promises;

exports.checkInternet = function checkInternet() {
    return dns.lookup('google.com')
        .then(() => true)
        .catch(() => false);
};

Upvotes: 4

Freddy Daniel
Freddy Daniel

Reputation: 651

I found a great and simple npm tool to detect internet connection. It's looks like more reliable.

First you need to install npm i check-internet-connected

Then you can call it like follows

  const checkInternetConnected = require('check-internet-connected');

  const config = {
    timeout: 5000, //timeout connecting to each server(A and AAAA), each try (default 5000)
    retries: 5,//number of retries to do before failing (default 5)
    domain: 'google.com'//the domain to check DNS record of
  }

  checkInternetConnected(config)
    .then(() => {
      console.log("Internet available");          
    }).catch((error) => {
      console.log("No internet", error);
    });

Upvotes: 3

robertklep
robertklep

Reputation: 203554

A quick and dirty way is to check if Node can resolve www.google.com:

require('dns').resolve('www.google.com', function(err) {
  if (err) {
     console.log("No connection");
  } else {
     console.log("Connected");
  }
});

This isn't entire foolproof, since your RaspPi can be connected to the Internet yet unable to resolve www.google.com for some reason, and you might also want to check err.type to distinguish between 'unable to resolve' and 'cannot connect to a nameserver so the connection might be down').

Upvotes: 63

Caio Wilson
Caio Wilson

Reputation: 371

It's not as foolproof as possible but get the job done:

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

just use a simple if(err) and treat the response adequately. :)

ps.: Please don't bother telling me 8.8.8.8 is not a name to be resolved, it's just a lookup for a highly available dns server from google. The intention is to check connectivity, not name resolution.

Upvotes: 11

Jaruba
Jaruba

Reputation: 1055

While robertklep's solution works, it is far from being the best choice for this. It takes about 3 minutes for dns.resolve to timeout and give an error if you don't have an internet connection, while dns.lookup responds almost instantly with the error ENOTFOUND.

So I made this function:

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

// example usage:
checkInternet(function(isConnected) {
    if (isConnected) {
        // connected to the internet
    } else {
        // not connected to the internet
    }
});

This is by far the fastest way of checking for internet connectivity and it avoids all errors that are not related to internet connectivity.

Upvotes: 52

Kristian Evensen
Kristian Evensen

Reputation: 1345

I had to build something similar in a NodeJS-app some time ago. The way I did it was to first use the networkInterfaces() function is the OS-module and then check if one or more interfaces have a non-internal IP.

If that was true, then I used exec() to start ping with a well-defined server (I like Google's DNS servers). By checking the return value of exec(), I know if ping was sucessful or not. I adjusted the number of pings based on the interface type. Forking a process introduces some overhead, but since this test is not performed too frequently in my app, I can afford it. Also, by using ping and IP-adresses, you dont depend on DNS being configured. Here is an example:

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

Upvotes: 19

Related Questions