mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-16 21:27:47 +00:00
commit
cf07849130
2 changed files with 33 additions and 29 deletions
|
|
@ -1,29 +1,27 @@
|
||||||
import http from 'http';
|
import fetch from 'node-fetch';
|
||||||
import https from 'https';
|
|
||||||
export async function checkLatency(url) {
|
export async function checkLatency(url, timeout = 5000) {
|
||||||
let request = http;
|
const controller = new AbortController()
|
||||||
if (url.startsWith('https')) {
|
const { signal } = controller
|
||||||
request = https;
|
const timeoutId = setTimeout(() => controller.abort(), timeout)
|
||||||
|
|
||||||
|
const start = Date.now()
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fetch(url, { signal })
|
||||||
|
const latency = Date.now() - start
|
||||||
|
return { url, latency }
|
||||||
|
} catch (err) {
|
||||||
|
logger.debug(`下载节点 ${url} 连接失败:`, err.message)
|
||||||
|
return { url, latency: Infinity }
|
||||||
|
} finally {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
}
|
}
|
||||||
return new Promise(resolve => {
|
|
||||||
const start = Date.now();
|
|
||||||
request
|
|
||||||
.get(url, res => {
|
|
||||||
res.on('data', () => {});
|
|
||||||
res.on('end', () => {
|
|
||||||
const latency = Date.now() - start;
|
|
||||||
resolve({ url, latency });
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on('error', err => {
|
|
||||||
logger.debug(`下载节点 ${url} 连接失败:`, err.message);
|
|
||||||
resolve({ url, latency: Infinity });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function findLowestLatencyUrl(urls) {
|
export async function findLowestLatencyUrl(urls) {
|
||||||
const results = await Promise.all(urls.map(checkLatency));
|
const results = await Promise.allSettled(urls.map(checkLatency));
|
||||||
const lowestLatencyResult = results.reduce((prev, curr) =>
|
const lowestLatencyResult = results.reduce((prev, curr) =>
|
||||||
prev.latency < curr.latency ? prev : curr
|
prev.latency < curr.latency ? prev : curr
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,18 +23,24 @@ const _request = async (url, options) => {
|
||||||
* @param {number} retry 重试次数
|
* @param {number} retry 重试次数
|
||||||
* @returns {Promise<Response>}
|
* @returns {Promise<Response>}
|
||||||
*/
|
*/
|
||||||
const request = (url, options, retry = 0) => {
|
const request = (url, options, retry = 0, timeout = 5000) => {
|
||||||
let err;
|
let err;
|
||||||
|
const controller = new AbortController()
|
||||||
|
const { signal } = controller
|
||||||
|
const timeoutId = setTimeout(() => controller.abort(), timeout)
|
||||||
|
|
||||||
const _fetch = async (url, options, retryCount = 0) => {
|
const _fetch = async (url, options, retryCount = 0) => {
|
||||||
if (retryCount > retry) {
|
if (retryCount > retry) {
|
||||||
throw new Error('Retry limit reached', err);
|
throw new Error('Retry limit reached', err);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return await _request(url, options);
|
return await _request(url, { signal, ...options });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.debug(`Fetch error: ${error.message}`);
|
logger.debug(error.name === 'AbortError' ? 'Request timed out' : `Fetch error: ${error.message}`);
|
||||||
err = error;
|
err = error;
|
||||||
return await _fetch(url, options, retryCount + 1);
|
return await _fetch(url, options, retryCount + 1);
|
||||||
|
} finally {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return _fetch(url, options);
|
return _fetch(url, options);
|
||||||
|
|
@ -49,8 +55,8 @@ const request = (url, options, retry = 0) => {
|
||||||
*/
|
*/
|
||||||
request.get = async (url, data, options) => {
|
request.get = async (url, data, options) => {
|
||||||
const params = new URLSearchParams(data);
|
const params = new URLSearchParams(data);
|
||||||
const { retry, ...restOptions } = options;
|
const { retry, timeout, ...restOptions } = options;
|
||||||
return request(`${url}?${params}`, restOptions, retry);
|
return request(`${url}?${params}`, restOptions, retry, timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -62,8 +68,8 @@ request.get = async (url, data, options) => {
|
||||||
*/
|
*/
|
||||||
request.post = async (url, data, options) => {
|
request.post = async (url, data, options) => {
|
||||||
const body = JSON.stringify(data);
|
const body = JSON.stringify(data);
|
||||||
const { retry, ...restOptions } = options;
|
const { retry, timeout, ...restOptions } = options;
|
||||||
return request(url, { ...restOptions, method: 'POST', body }, retry);
|
return request(url, { ...restOptions, method: 'POST', body }, retry, timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default request;
|
export default request;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue