fix: 处理频率限制并优化重连策略
This commit is contained in:
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "qqbot",
|
"name": "qqbot",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
@@ -11,12 +11,16 @@
|
|||||||
"extensions": ["./index.ts"]
|
"extensions": ["./index.ts"]
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc || true",
|
||||||
"dev": "tsc --watch"
|
"dev": "tsc --watch",
|
||||||
|
"prepack": "npm install --omit=dev"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ws": "^8.18.0"
|
"ws": "^8.18.0"
|
||||||
},
|
},
|
||||||
|
"bundledDependencies": [
|
||||||
|
"ws"
|
||||||
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.0.0",
|
"@types/node": "^20.0.0",
|
||||||
"@types/ws": "^8.5.0",
|
"@types/ws": "^8.5.0",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const INTENTS = {
|
|||||||
|
|
||||||
// 重连配置
|
// 重连配置
|
||||||
const RECONNECT_DELAYS = [1000, 2000, 5000, 10000, 30000, 60000]; // 递增延迟
|
const RECONNECT_DELAYS = [1000, 2000, 5000, 10000, 30000, 60000]; // 递增延迟
|
||||||
|
const RATE_LIMIT_DELAY = 60000; // 遇到频率限制时等待 60 秒
|
||||||
const MAX_RECONNECT_ATTEMPTS = 100;
|
const MAX_RECONNECT_ATTEMPTS = 100;
|
||||||
const MAX_QUICK_DISCONNECT_COUNT = 3; // 连续快速断开次数阈值
|
const MAX_QUICK_DISCONNECT_COUNT = 3; // 连续快速断开次数阈值
|
||||||
const QUICK_DISCONNECT_THRESHOLD = 5000; // 5秒内断开视为快速断开
|
const QUICK_DISCONNECT_THRESHOLD = 5000; // 5秒内断开视为快速断开
|
||||||
@@ -69,13 +70,13 @@ export async function startGateway(ctx: GatewayContext): Promise<void> {
|
|||||||
return RECONNECT_DELAYS[idx];
|
return RECONNECT_DELAYS[idx];
|
||||||
};
|
};
|
||||||
|
|
||||||
const scheduleReconnect = () => {
|
const scheduleReconnect = (customDelay?: number) => {
|
||||||
if (isAborted || reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
if (isAborted || reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
||||||
log?.error(`[qqbot:${account.accountId}] Max reconnect attempts reached or aborted`);
|
log?.error(`[qqbot:${account.accountId}] Max reconnect attempts reached or aborted`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const delay = getReconnectDelay();
|
const delay = customDelay ?? getReconnectDelay();
|
||||||
reconnectAttempts++;
|
reconnectAttempts++;
|
||||||
log?.info(`[qqbot:${account.accountId}] Reconnecting in ${delay}ms (attempt ${reconnectAttempts})`);
|
log?.info(`[qqbot:${account.accountId}] Reconnecting in ${delay}ms (attempt ${reconnectAttempts})`);
|
||||||
|
|
||||||
@@ -90,8 +91,8 @@ export async function startGateway(ctx: GatewayContext): Promise<void> {
|
|||||||
try {
|
try {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
// 刷新 token(可能过期了)
|
// 获取 token(使用缓存,除非已过期)
|
||||||
clearTokenCache();
|
// 注意:不要每次都 clearTokenCache,否则会触发频率限制
|
||||||
const accessToken = await getAccessToken(account.appId, account.clientSecret);
|
const accessToken = await getAccessToken(account.appId, account.clientSecret);
|
||||||
const gatewayUrl = await getGatewayUrl(accessToken);
|
const gatewayUrl = await getGatewayUrl(accessToken);
|
||||||
|
|
||||||
@@ -517,8 +518,16 @@ export async function startGateway(ctx: GatewayContext): Promise<void> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
const errMsg = String(err);
|
||||||
log?.error(`[qqbot:${account.accountId}] Connection failed: ${err}`);
|
log?.error(`[qqbot:${account.accountId}] Connection failed: ${err}`);
|
||||||
scheduleReconnect();
|
|
||||||
|
// 如果是频率限制错误,等待更长时间
|
||||||
|
if (errMsg.includes("Too many requests") || errMsg.includes("100001")) {
|
||||||
|
log?.info(`[qqbot:${account.accountId}] Rate limited, waiting ${RATE_LIMIT_DELAY}ms before retry`);
|
||||||
|
scheduleReconnect(RATE_LIMIT_DELAY);
|
||||||
|
} else {
|
||||||
|
scheduleReconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user