背景
用户在应用 electron app 的时候,常常会遇到白屏,服务器异样,网络异样等状况,然而用户却不晓得如何解决,所以须要提供一个能够给用户自行诊断网络的性能,一来不便用户本人疾速定位问题,自行解决,二来查看开发排查问题的工夫。
例如飞书在断开主动自行诊断网络状态,提醒用户设置网络。
性能需要
性能需要能够参考飞书,飞书的网络诊断就是比拟残缺的交互例子
需要内容:
- 反对网络状态诊断 – 检测网络是否在线或离线
- 反对 nds 解析诊断 - 检测服务器域名是否能胜利解析 dns
- 反对代理诊断 – 检测电脑是否开启了代理
- 服务稳定性剖析 – 检测服务器域名是否可连通
性能 | 阐明 | web | app |
---|---|---|---|
反对网络状态诊断 | 检测网络是否在线或离线 | ☑️ | ☑️ |
反对 nds 解析诊断 | 检测服务器域名是否能胜利解析 dns | ✖️ | ☑️ |
反对代理诊断 | 检测电脑是否开启了代理 | ✖️ | ☑️ |
服务稳定性剖析 | 检测服务器域名是否可连通 | ☑️ | ☑️ |
技术选型
web 技术诊断
有时候也有这样的需要,我想诊断 web 内所有域名服务器地址的可连通性。
js 引擎(浏览器)并没有提供 ping 相干的能力,并且也无奈通过 xhr 来做这种事件,因为这会波及到跨域,那么身下的计划就是通过资源申请,通过的做法就是发送一个 img 的申请,而最通用的就是申请服务器地址的 favicon.ico。刚好就有这这样的一个插件能够帮忙做这样的事件:ping.js
装置 ping.js
$ npm install ping.js
应用 demo,data 返回的是 rtt 值
var p = new Ping();
// Using callback
p.ping("https://github.com", function(err, data) {
// Also display error if err is returned.
if (err) {console.log("error loading resource")
data = data + " " + err;
}
document.getElementById("ping-github").innerHTML = data;
});
// You may use Promise if the browser supports ES6
p.ping("https://github.com")
.then(data => {console.log("Successful ping:" + data);
})
.catch(data => {console.error("Ping failed:" + data);
})
很显著这种形式对于很多场景都是不实用的,比方一个我的项目波及到其余域名的申请。
app 技术诊断
app 是原生利用,能够调用到计算机底层的 api,就算不借助插件,都能够通过关上终端,ping 域名,获取返回值,所以 app 做这件事件是非常容易的,这里咱们针对 electron 利用举例
诊断流程
获取域名信息
网络信息的获取分为两种形式:
1. 业务侧有输入框,用户手动输出
2. 获取我的项目配置的域名服务器地址
网络状态
网络问题产生时,网络状态往往是第一察看因素。如何去判断网络是否连贯上了网络:
- 通用的判断形式:navigator.onLine,然而这个形式只会在机器未连贯到局域网或路由器时返回 false,其余状况下均返回 true。也就是说如果用户路由器自身网络就不通的状况下是没有方法判断的。
- 进阶判断形式:收回一个申请,看申请返回的状态码或者拜访一个网络资源,比方图片。收回一个网络申请的网站起源,能够是一个固定稳固的动态域名服务器。
DNS 解析
依据域名,查问出对应 IP 信息。服务器域名,唯有正确的解析出 IP 后,能力胜利进行后续的网络连接流程,这里采纳 node 的 nds 模块即可。Desktop: dns.lookup(node)
ping 连通性 与 traceRoute 连通性
对于如何诊断,以及 ping 和 traceroute 的原理,能够这篇博客:https://www.cnblogs.com/seanloveslife/p/11941736.html。
这里咱们会用一个 node 的插件 node-net-ping 来实现这些操作,该插件不仅反对 ping 同时也反对 traceroute,并且对这些操作的异样进行了很好的封装,简化调用过程。
如果在 eletron 应用过程中遇到问题:能够应用该插件 node-ping,仅反对 ping
下载日志
下载日志的思路就是把之前每一步诊断异样的日志通过 electron-log 或者其余日志插件写入到本地文件,再将本地的日志文件压缩,最初容许用户保留在指定的目录上面。
这里重点看下压缩的过程:
压缩须要用到插件 archiver
const fs = require('fs')
const archiver = require('archiver')
/**
* 压缩日志
* @param {string} sourceFilePath
* @param {string} outputFilePath
* @returns
*/
const compressLogFolder = (sourceFilePath, outputFilePath) => {return new Promise((resolve, reject) => {
try {const outputStream = fs.createwriteStream(outputFilePath);
const archive = archiver('zip', { zlib: { level: 9}})
archive.pipe(outputStream)
const data = fs. readFileSync (sourceFilePath, 'utf8');
archive.append(data.toString(), {name: 'network.log'})
archive.finalize();
outputStream.on('close', (res) = resolve(res)) ;
outputStream.on('error', (err) = reject(err));
} catch (error) {reject (error)
}
})
}