Files
yenai-plugin/model/State/Network.js
2024-04-13 20:21:36 +08:00

147 lines
4.5 KiB
JavaScript
Raw 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 } 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" }
]
/**
* 获取网络测试列表。
* @returns {Promise<Array>} 返回一个Promise该Promise解析为网络测试结果的数组。
*/
export function getNetworkTestList() {
const { psTestSites, psTestTimeout } = Config.state
if (!psTestSites) {
return Promise.resolve([])
}
// 验证配置项
if (typeof psTestSites !== "boolean" && psTestSites !== "default" && !Array.isArray(psTestSites)) {
throw new Error("[yenai-plugin][state]参数错误请检查psTestSites是否填写正确")
}
let testList = psTestSites === true || psTestSites === "default" ? defList : psTestSites
// 如果testList为空直接返回空数组的Promise
if (testList.length === 0) {
return Promise.resolve([])
}
// 使用Promise.all集中处理所有Promise
let currentRequests = 0
return Promise.all(testList.map((site) => {
currentRequests++
return handleSite(site, psTestTimeout).finally(() => {
if (--currentRequests === 0) {
logger.debug("[yenai-plugin][state]已完成所有网络测试")
}
})
}))
}
// 封装处理每个测试站点逻辑到一个单独的函数
const handleSite = (site, TestTimeout) => {
return getNetworkLatency(site.url, TestTimeout)
.then(res => ({ first: site.name, tail: res }))
.catch(error => {
logger.error(`[yenai-plugin][state]Error testing site: ${site.name}`, error)
return { first: site.name, tail: "Error" } // 捕获错误并返回一个错误标记
})
}
/**
* 网络测试
* @param {string} url 测试的url
* @param {number} [timeoutTime] 超时时间
* @returns {string}
*/
async function getNetworkLatency(url, timeoutTime = 5000) {
// 使用try-catch处理import可能抛出的异常
let AbortController
try {
AbortController = globalThis.AbortController || await import("abort-controller")
} catch (error) {
logger.error("无法加载AbortController:", error)
throw new Error("网络请求控制器加载失败")
}
const controller = new AbortController()
const timeout = setTimeout(() => {
controller.abort()
}, timeoutTime)
try {
const startTime = Date.now()
let { status } = await request.get(url, {
signal: controller.signal,
origError: true,
closeLogError: true
})
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>`
} catch (error) {
if (error.name === "AbortError") {
return "<span style='color:#F44336'>timeout</span>"
}
if (error.message.includes("ECONNRESET")) {
logger.error("网络请求发生了 ECONNRESET 错误:", error.message)
return "<span style='color:#F44336'>ECONNRESET</span>"
}
logger.error("网络请求过程中发生错误:", error)
return "<span style='color:#F44336'>error</span>"
} finally {
clearTimeout(timeout)
}
}
/** 获取当前网速 */
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, false, false)
let _tx = getFileSize(v.tx_sec, false, false)
data.push({
first: v.iface,
tail: `${_tx}/s | ↓${_rx}/s`
})
}
}
return data.length === 0 ? false : data
}