Merge pull request #49 from HDTianRu/main

修复无法下载资源
This commit is contained in:
bietiaop 2024-08-18 15:58:05 +08:00 committed by GitHub
commit cf07849130
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 29 deletions

View file

@ -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
); );

View file

@ -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;