Files
yenai-plugin/model/State/Network.js
2024-05-18 14:54:41 +08:00

170 lines
5.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Config } from "../../components/index.js"
import request from "../../lib/request/request.js"
import Monitor from "./Monitor.js"
import { getFileSize, createAbortCont } from "./utils.js"
const defList = [
{ name: "Baidu", url: "https://baidu.com" },
{ name: "Google", url: "https://google.com" },
{ name: "Github", url: "https://github.com" },
{ name: "Gitee", url: "https://gitee.com" },
{ name: "TRSS", url: "https://trss.me" }
]
/**
* 获取网络测试列表。
* @param e
* @returns {Promise<Array>} 返回一个Promise该Promise解析为网络测试结果的数组。
*/
export function getNetworkTestList(e) {
const { psTestSites, psTestTimeout } = Config.state
if (!psTestSites) {
return Promise.resolve([])
}
const parsedData = parseConfig(psTestSites, psTestTimeout)
if (!parsedData.show) {
return Promise.resolve([])
}
if (parsedData.show === "pro" && !e.isPro) {
return Promise.resolve([])
}
if (parsedData.list.length === 0) {
return Promise.resolve([])
}
// 使用Promise.all集中处理所有Promise
let currentRequests = 0
return Promise.all(parsedData.list.map((site) => {
currentRequests++
return handleSite(site).finally(() => {
if (--currentRequests === 0) {
logger.debug("[Yenai-Plugin][状态]已完成所有网络测试")
}
})
}))
}
const handleSite = (site) => {
return getNetworkLatency(site.url, site.timeout, site.useProxy)
.then(res => ({ first: site.name, tail: res }))
.catch(error => {
const errorMsg = handleError(error, site.name)
const errorSpan = `<span style='color:#F44336'>${errorMsg}</span>`
return { first: site.name, tail: errorSpan }
})
}
const handleError = (error, siteName) => {
let errorMsg = "error"
const prefix = "[Yenai-Plugin][状态]"
if (error.name === "AbortError") {
logger.warn(`${prefix}请求 ${siteName} 超时`)
errorMsg = "timeout"
} else if (error.message.includes("ECONNRESET")) {
logger.warn(`${prefix}请求 ${siteName} 发生了 ECONNRESET 错误:`, error.message)
errorMsg = "econnreset"
} else {
logger.error(`${prefix}请求 ${siteName} 过程中发生错误:`, error.message)
}
return errorMsg
}
/**
* 解析配置参数并返回配置对象。
* @param {Array | string | boolean} psTestSites - 预期应该是对象包含show,list,timeout
* @param {number} psTestTimeout - 保留老配置文件psTestTimeout
* @returns {object} 包含配置信息的对象。
*/
function parseConfig(psTestSites, psTestTimeout) {
let data = {
show: "pro",
list: [],
timeout: psTestTimeout ?? 5000
}
if (Array.isArray(psTestSites)) {
data.list = psTestSites
} else if (typeof psTestSites === "object") {
data = { ...data, ...psTestSites }
} else if (
(typeof psTestSites === "boolean" && psTestSites === true) ||
(typeof psTestSites === "string" && psTestSites === "default")
) {
data.show = true
data.list = defList
}
return data
}
/**
* 网络测试
* @param {string} url 测试的url
* @param {number} [timeoutTime] 超时时间
* @param {boolean} useProxy 是否使用代理
* @returns {string}
*/
async function getNetworkLatency(url, timeoutTime = 5000, useProxy = false) {
let { controller, clearTimeout } = await createAbortCont(timeoutTime)
try {
const startTime = Date.now()
let { status } = await request.get(url, {
signal: controller.signal,
origError: true,
outErrorLog: false,
agent: !!useProxy
})
const endTime = Date.now()
let delay = endTime - startTime
const COLOR_DELAY_GOOD = "#188038"
const COLOR_DELAY_AVERAGE = "#d68100"
const COLOR_DELAY_BAD = "#F44336"
const COLOR_STATUS_OK = "#188038"
const COLOR_STATUS_WARNING = "#FF9800"
const COLOR_STATUS_DANGER = "#9C27B0"
const COLOR_STATUS_INFO = "#03A9F4"
const COLOR_STATUS_BAD = "#F44336"
let color = delay > 2000
? COLOR_DELAY_BAD
: delay > 500
? COLOR_DELAY_AVERAGE
: COLOR_DELAY_GOOD
let statusColor = status >= 500
? COLOR_STATUS_DANGER
: status >= 400
? COLOR_STATUS_BAD
: status >= 300
? COLOR_STATUS_WARNING
: status >= 200
? COLOR_STATUS_OK
: status >= 100
? COLOR_STATUS_INFO
: ""
return `<span style='color:${statusColor}'>${status}</span> | <span style='color:${color}'>${delay}ms</span>`
} finally {
clearTimeout()
}
}
/** 获取当前网速 */
export function getNetwork() {
let network = Monitor.network
if (!network || network.length === 0) {
return false
}
let data = []
for (let v of network) {
if (v.rx_sec != null && v.tx_sec != null) {
let _rx = getFileSize(v.rx_sec, { showByte: false, showSuffix: false })
let _tx = getFileSize(v.tx_sec, { showByte: false, showSuffix: false })
data.push({
first: v.iface,
tail: `${_tx}/s | ↓${_rx}/s`
})
}
}
return data.length === 0 ? false : data
}