mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
fix: 更新逻辑
This commit is contained in:
@@ -7,6 +7,11 @@ interface ServerRkeyData {
|
|||||||
expired_time: number;
|
expired_time: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface UrlFailureInfo {
|
||||||
|
count: number;
|
||||||
|
lastTimestamp: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class RkeyManager {
|
export class RkeyManager {
|
||||||
serverUrl: string[] = [];
|
serverUrl: string[] = [];
|
||||||
logger: LogWrapper;
|
logger: LogWrapper;
|
||||||
@@ -15,8 +20,7 @@ export class RkeyManager {
|
|||||||
private_rkey: '',
|
private_rkey: '',
|
||||||
expired_time: 0,
|
expired_time: 0,
|
||||||
};
|
};
|
||||||
private failureCount: number = 0;
|
private urlFailures: Map<string, UrlFailureInfo> = new Map();
|
||||||
private lastFailureTimestamp: number = 0;
|
|
||||||
private readonly FAILURE_LIMIT: number = 8;
|
private readonly FAILURE_LIMIT: number = 8;
|
||||||
private readonly ONE_DAY: number = 24 * 60 * 60 * 1000;
|
private readonly ONE_DAY: number = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
@@ -26,34 +30,74 @@ export class RkeyManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getRkey() {
|
async getRkey() {
|
||||||
const now = new Date().getTime();
|
const availableUrls = this.getAvailableUrls();
|
||||||
if (now - this.lastFailureTimestamp > this.ONE_DAY) {
|
if (availableUrls.length === 0) {
|
||||||
this.failureCount = 0; // 重置失败计数器
|
this.logger.logError('[Rkey] 所有服务均已禁用, 图片使用FallBack机制');
|
||||||
}
|
throw new Error('获取rkey失败:所有服务URL均已被禁用');
|
||||||
|
|
||||||
if (this.failureCount >= this.FAILURE_LIMIT) {
|
|
||||||
this.logger.logError('[Rkey] 服务存在异常, 图片使用FallBack机制');
|
|
||||||
throw new Error('获取rkey失败次数过多,请稍后再试');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isExpired()) {
|
if (this.isExpired()) {
|
||||||
try {
|
try {
|
||||||
await this.refreshRkey();
|
await this.refreshRkey();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`${e}`);//外抛
|
throw new Error(`${e}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.rkeyData;
|
return this.rkeyData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getAvailableUrls(): string[] {
|
||||||
|
return this.serverUrl.filter(url => !this.isUrlDisabled(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
private isUrlDisabled(url: string): boolean {
|
||||||
|
const failureInfo = this.urlFailures.get(url);
|
||||||
|
if (!failureInfo) return false;
|
||||||
|
|
||||||
|
const now = new Date().getTime();
|
||||||
|
// 如果已经过了一天,重置失败计数
|
||||||
|
if (now - failureInfo.lastTimestamp > this.ONE_DAY) {
|
||||||
|
failureInfo.count = 0;
|
||||||
|
this.urlFailures.set(url, failureInfo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return failureInfo.count >= this.FAILURE_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateUrlFailure(url: string) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
const failureInfo = this.urlFailures.get(url) || { count: 0, lastTimestamp: 0 };
|
||||||
|
|
||||||
|
// 如果已经过了一天,重置失败计数
|
||||||
|
if (now - failureInfo.lastTimestamp > this.ONE_DAY) {
|
||||||
|
failureInfo.count = 1;
|
||||||
|
} else {
|
||||||
|
failureInfo.count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
failureInfo.lastTimestamp = now;
|
||||||
|
this.urlFailures.set(url, failureInfo);
|
||||||
|
|
||||||
|
if (failureInfo.count >= this.FAILURE_LIMIT) {
|
||||||
|
this.logger.logError(`[Rkey] URL ${url} 已被禁用,失败次数达到 ${this.FAILURE_LIMIT} 次`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isExpired(): boolean {
|
isExpired(): boolean {
|
||||||
const now = new Date().getTime() / 1000;
|
const now = new Date().getTime() / 1000;
|
||||||
return now > this.rkeyData.expired_time;
|
return now > this.rkeyData.expired_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshRkey() {
|
async refreshRkey() {
|
||||||
//刷新rkey
|
const availableUrls = this.getAvailableUrls();
|
||||||
for (const url of this.serverUrl) {
|
|
||||||
|
if (availableUrls.length === 0) {
|
||||||
|
this.logger.logError('[Rkey] 所有服务均已禁用');
|
||||||
|
throw new Error('获取rkey失败:所有服务URL均已被禁用');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const url of availableUrls) {
|
||||||
try {
|
try {
|
||||||
const temp = await RequestUtil.HttpGetJson<ServerRkeyData>(url, 'GET');
|
const temp = await RequestUtil.HttpGetJson<ServerRkeyData>(url, 'GET');
|
||||||
this.rkeyData = {
|
this.rkeyData = {
|
||||||
@@ -61,15 +105,13 @@ export class RkeyManager {
|
|||||||
private_rkey: temp.private_rkey.slice(6),
|
private_rkey: temp.private_rkey.slice(6),
|
||||||
expired_time: temp.expired_time
|
expired_time: temp.expired_time
|
||||||
};
|
};
|
||||||
this.failureCount = 0;
|
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.logError(`[Rkey] 异常服务 ${url} 异常 / `, e);
|
this.logger.logError(`[Rkey] 异常服务 ${url} 异常 / `, e);
|
||||||
this.failureCount++;
|
this.updateUrlFailure(url);
|
||||||
this.lastFailureTimestamp = new Date().getTime();
|
|
||||||
//是否为最后一个url
|
if (url === availableUrls[availableUrls.length - 1]) {
|
||||||
if (url === this.serverUrl[this.serverUrl.length - 1]) {
|
throw new Error(`获取rkey失败: ${e}`);
|
||||||
throw new Error(`获取rkey失败: ${e}`);//外抛
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user