add reconnection mechanism

This commit is contained in:
被遗忘的记忆
2024-08-31 08:40:33 +08:00
committed by GitHub
parent f0fb0d806e
commit ff2a9ca3be
+78 -9
View File
@@ -794,17 +794,86 @@ class YouProvider {
const cid = `c0_${uuidV4()}`;
await page.goto(`https://you.com/search?q=${encodeURIComponent(userQuery)}&fromSearchBar=true&tbm=youchat&chatMode=custom&cid=${cid}`, {waitUntil: "domcontentloaded"});
// 延迟发送请求 Promise
const delayedRequest = new Promise((resolve) => {
setTimeout(() => {
console.log("正在发送请求");
emitter.emit("start", traceId);
resolve();
}, 4000);
});
// 检查连接状态和盾拦截
async function checkConnectionAndCloudflare(page, timeout = 60000) {
try {
const response = await Promise.race([
page.evaluate(async (url) => {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 50000);
try {
const res = await fetch(url, {
method: 'GET',
signal: controller.signal
});
clearTimeout(timeoutId);
// 读取响应的前几个字节,确保连接已经建立
const reader = res.body.getReader();
const { done } = await reader.read();
if (!done) {
await reader.cancel();
}
return {
status: res.status,
headers: Object.fromEntries(res.headers.entries())
};
} catch (error) {
if (error.name === 'AbortError') {
throw new Error('Request timed out');
}
throw error;
}
}, url),
new Promise((_, reject) => setTimeout(() => reject(new Error('Evaluation timed out')), timeout))
]);
if (response.status === 403 && response.headers['cf-chl-bypass']) {
return { connected: false, cloudflareDetected: true };
}
return { connected: true, cloudflareDetected: false };
} catch (error) {
console.error("Connection check error:", error);
return { connected: false, cloudflareDetected: false, error: error.message };
}
}
// 延迟发送请求并验证连接的函数
async function delayedRequestWithRetry(maxRetries = 2, totalTimeout = 120000) {
const startTime = Date.now();
for (let attempt = 1; attempt <= maxRetries; attempt++) {
if (Date.now() - startTime > totalTimeout) {
console.error("总体超时,连接失败");
emitter.emit("error", new Error("Total timeout reached"));
return false;
}
await new Promise(resolve => setTimeout(resolve, 4000)); // 4秒延迟
console.log(`尝试发送请求 (尝试 ${attempt}/${maxRetries})`);
const { connected, cloudflareDetected, error } = await checkConnectionAndCloudflare(page);
if (connected) {
console.log("连接成功,开始发送请求");
emitter.emit("start", traceId);
return true;
} else if (cloudflareDetected) {
console.error("检测到 Cloudflare 拦截");
emitter.emit("error", new Error("Cloudflare challenge detected"));
return false;
} else {
console.log(`连接失败,准备重试 (${attempt}/${maxRetries}). 错误: ${error || 'Unknown'}`);
}
}
console.error("达到最大重试次数,连接失败");
emitter.emit("error", new Error("Failed to establish connection after maximum retries"));
return false;
}
try {
await delayedRequest;
const connectionEstablished = await delayedRequestWithRetry();
if (!connectionEstablished) {
return { completion: emitter, cancel: () => {} };
}
await page.evaluate(
async (url, traceId, customEndMarker) => {