在 Raspberry Pi 上安装了 NodeJS,有没有办法检查 rPi 是否通过 NodeJs 连接到互联网?
10 回答
一种快速而肮脏的方法是检查 Node 是否可以解决www.google.com
:
require('dns').resolve('www.google.com', function(err) {
if (err) {
console.log("No connection");
} else {
console.log("Connected");
}
});
这并不是万无一失的,因为您的 RaspPi 可以连接到 Internet 但由于www.google.com
某种原因无法解析,您可能还需要检查err.type
以区分“无法解析”和“无法连接到名称服务器,因此连接可能下来”)。
虽然 robertklep 的解决方案有效,但它远非最佳选择。dns.resolve
如果您没有互联网连接,超时并给出错误大约需要 3 分钟,而dns.lookup
几乎立即响应错误ENOTFOUND
。
所以我做了这个功能:
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
}
});
这是迄今为止检查互联网连接的最快方法,它避免了所有与互联网连接无关的错误。
前段时间我不得不在 NodeJS 应用程序中构建类似的东西。我这样做的方法是首先使用networkInterfaces()函数是操作系统模块,然后检查一个或多个接口是否具有非内部 IP。
如果这是真的,那么我使用exec()开始 ping 一个定义明确的服务器(我喜欢 Google 的 DNS 服务器)。通过检查 exec() 的返回值,我知道 ping 是否成功。我根据接口类型调整了 ping 的数量。分叉一个进程会带来一些开销,但由于这个测试在我的应用程序中执行的并不频繁,我可以负担得起。此外,通过使用 ping 和 IP 地址,您不必依赖正在配置的 DNS。这是一个例子:
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")
});
它不是尽可能万无一失,但可以完成工作:
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
});
只需使用简单if(err)
的并充分对待响应。:)
ps.:请不要告诉我 8.8.8.8 不是要解析的名称,它只是从 google 查找高可用性 dns 服务器。目的是检查连接性,而不是名称解析。
这是一个单行:(节点 10.6+)
let isConnected = !!await require('dns').promises.resolve('google.com').catch(()=>{});
由于我在这里关注其他解决方案中的 DNS 缓存,因此我尝试使用 http2 进行实际连接测试。我认为这是测试互联网连接的最佳方式,因为它不会发送太多数据,也不依赖单独的 DNS 解析,而且速度非常快。
请注意,这是在 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);
编辑:如果有人感兴趣,我把它做成一个包。
我找到了一个伟大而简单的 npm 工具来检测互联网连接。它看起来更可靠。
首先你需要安装
npm i check-internet-connected
然后你可以像下面这样调用它
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);
});
从 2019 年起,您可以使用DNS 承诺查找。
注意此 API 是实验性的。
const dns = require('dns').promises;
exports.checkInternet = function checkInternet() {
return dns.lookup('google.com')
.then(() => true)
.catch(() => false);
};
检查我们的浏览器的互联网连接是否可用非常有帮助。
var internetAvailable = require("internet-available");
internetAvailable().then(function(){
console.log("Internet available",internetAvailable);
}).catch(function(){
console.log("No internet");
});
更多[互联网可用][1]:https ://www.npmjs.com/package/internet-available
这是一个非常简单的函数,不导入任何东西,而是利用JS内置函数,并且只能在调用时执行,它不监控丢失/互联网连接;与使用缓存的某些答案不同,此结果是准确的,因为它不返回缓存结果。
const connected = fetch("https://google.com", {
method: "FET",
cache: "no-cache",
headers: { "Content-Type": "application/json" },
referrerPolicy: "no-referrer",
}).then(() => true)
.catch(() => false);
使用 await 调用它(确保你在异步函数中,否则你会得到一个承诺)
console.log(await connected);