From 1ebec80515fc6cc0a347b1ae06340db4c7da1054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=B6=E7=91=BE?= <74231782+sj817@users.noreply.github.com> Date: Thu, 16 Jan 2025 00:33:52 +0800 Subject: [PATCH] fix: remove deprecated configuration files and enhance WebSocket client reconnection logic --- packages/core/default/config/groups.yaml | 70 ---------------- packages/core/default/config/privates.yaml | 31 ------- packages/core/default/config/render.json | 4 +- .../core/src/adapter/render/connect/client.ts | 84 ++++++++++++++++++- 4 files changed, 82 insertions(+), 107 deletions(-) delete mode 100644 packages/core/default/config/groups.yaml delete mode 100644 packages/core/default/config/privates.yaml diff --git a/packages/core/default/config/groups.yaml b/packages/core/default/config/groups.yaml deleted file mode 100644 index 589c1251..00000000 --- a/packages/core/default/config/groups.yaml +++ /dev/null @@ -1,70 +0,0 @@ -# 详细配置请参考: https://karin.fun/start/file - -# 全局默认配置 -default: - # 群聊、频道中所有消息冷却时间,单位秒,0则无限制 - cd: 0 - # 群聊、频道中 每个人的消息冷却时间,单位秒,0则无限制。注意,开启后所有消息都会进CD,无论是否触发插件。 - userCD: 1 - # 机器人响应模式,0-所有 1-仅@机器人 2-仅回应管理员 3-仅回应别名 4-别名或@机器人 5-管理员无限制,成员别名或@机器人 6-仅回应主人 - mode: 0 - - # 机器人别名 设置后别名+指令触发机器人 - alias: - - k - - # 白名单插件、功能,只有在白名单中的插件、功能才会响应 `karin-plugin-test:app.js` `karin-plugin-test:测试转发` - enable: [] - - # 黑名单插件、功能,黑名单中的插件、功能不会响应 `karin-plugin-test:app.js` `karin-plugin-test:测试转发` - disable: [] - - # 群、频道成员单独黑名单 - memberDisable: [] - - # 群、频道成员单独白名单 - memberEnable: [] - -# 单个Bot全局配置 -Bot:selfId: - cd: 0 - userCD: 1 - mode: 0 - alias: [] - enable: [] - disable: [] - memberDisable: [] - memberEnable: [] - -# 单个Bot:单个群 配置 -Bot:selfId:groupId: - cd: 0 - userCD: 1 - mode: 0 - alias: [] - enable: [] - disable: [] - memberDisable: [] - memberEnable: [] - -# 单个Bot:单个频道 配置 -Bot:selfId:guildId: - cd: 0 - userCD: 1 - mode: 0 - alias: [] - enable: [] - disable: [] - memberDisable: [] - memberEnable: [] - -# 单个Bot:单个频道:单个子频道 配置 -Bot:selfId:guildId:channelId: - cd: 0 - userCD: 1 - mode: 0 - alias: [] - enable: [] - disable: [] - memberDisable: [] - memberEnable: [] diff --git a/packages/core/default/config/privates.yaml b/packages/core/default/config/privates.yaml deleted file mode 100644 index ee421fb5..00000000 --- a/packages/core/default/config/privates.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# 详细配置请参考: https://karin.fun/start/file - -# 全局默认配置 -default: - # 好友消息冷却时间,单位秒,0则无限制 - cd: 0 - # 机器人响应模式(私聊没有群聊那么多模式),0-所有 2-仅回应管理员 3-仅回应别名 5-管理员无限制,非管理员别名 6-仅回应主人 - mode: 0 - # 机器人别名 设置后别名+指令触发机器人 - alias: - - k - # 白名单插件、功能,只有在白名单中的插件、功能才会响应 `karin-plugin-test:app.js` `karin-plugin-test:测试转发` - enable: [] - # 黑名单插件、功能,黑名单中的插件、功能不会响应 `karin-plugin-test:app.js` `karin-plugin-test:测试转发` - disable: [] - -# 单个Bot默认配置 -Bot:selfId: - cd: 0 - mode: 0 - alias: [] - enable: [] - disable: [] - -# 单个Bot:单个好友、频道成员 配置 -Bot:selfId:userId: - cd: 0 - mode: 0 - alias: [] - enable: [] - disable: [] diff --git a/packages/core/default/config/render.json b/packages/core/default/config/render.json index 88088f84..cdee35e8 100644 --- a/packages/core/default/config/render.json +++ b/packages/core/default/config/render.json @@ -4,8 +4,8 @@ }, "ws_client": [ { - "enable": false, - "url": "ws://127.0.0.1:7005", + "enable": true, + "url": "ws://127.0.0.1:7005/ws", "token": "123456" } ], diff --git a/packages/core/src/adapter/render/connect/client.ts b/packages/core/src/adapter/render/connect/client.ts index cf66804d..a65aeef9 100644 --- a/packages/core/src/adapter/render/connect/client.ts +++ b/packages/core/src/adapter/render/connect/client.ts @@ -4,10 +4,74 @@ import { WebSocketRender } from './ws' import { render } from '@/utils/config/render' /** - * @description WebSocket客户端渲染 - * @class WebSocketServerRenderer + * @description WebSocket客户端渲染器 + * @class WebSocketClientRenderer */ -export class WebSocketClientRenderer extends WebSocketRender { } +export class WebSocketClientRenderer extends WebSocketRender { + /** 重连次数 */ + private reconnectCount: number = 0 + /** 最大重连次数,设为-1表示无限重连 */ + private maxReconnectAttempts: number = -1 + /** 基连延迟(ms) */ + private baseDelay: number = 5000 + /** WebSocket连接URL */ + private url: string + /** 连接headers */ + private headers: Record + + constructor (socket: WebSocket, url: string, headers: Record) { + super(socket) + this.url = url + this.headers = headers + } + + /** + * @description 重连逻辑 + * @param isPrint 是否打印日志 + */ + reconnect = (isPrint = false) => { + if (this.maxReconnectAttempts !== -1 && this.reconnectCount >= this.maxReconnectAttempts) { + logger.error(`[render][WebSocket] 连接失败次数过多(${this.reconnectCount}次), 已停止重连: ${this.url}`) + return + } + + this.reconnectCount++ + const delay = this.baseDelay + const delaySeconds = delay / 1000 + + if (isPrint) { + logger.warn(`[render][WebSocket][${this.reconnectCount}] 连接失败,${delaySeconds}秒后将重连: ${this.url}`) + } + + setTimeout(() => { + try { + const socket = new WebSocket(this.url, { headers: this.headers }) + this.socket = socket + + socket.once('open', async () => { + logger.info(`[render][WebSocket] 连接成功: ${this.url}`) + await this.init() + this.reconnectCount = 0 + }) + + socket.once('error', (error) => { + logger.debug(error) + logger.error(`[render][WebSocket][${this.reconnectCount}] 连接错误: ${error.message},${delaySeconds}秒后将重连: ${this.url}`) + socket.removeAllListeners() + socket.close() + this.reconnect(false) + }) + + socket.once('close', () => { + this.reconnect(true) + }) + } catch (error) { + logger.debug(error) + this.reconnect() + } + }, delay) + } +} /** * @description 创建puppeteer WebSocket客户端 @@ -22,12 +86,24 @@ export const createWebSocketRenderClient = () => { return Promise.allSettled(cfg.ws_client.map(async (item) => { const { url, token, enable } = item if (!enable) return + const headers = { Authorization: crypto.createHash('md5').update(`Bearer ${token}`).digest('hex') } const socket = new WebSocket(url, { headers }) + const renderer = new WebSocketClientRenderer(socket, url, headers) socket.once('open', async () => { logger.info(`[render][WebSocket] 连接成功: ${url}`) - await new WebSocketClientRenderer(socket).init() + await renderer.init() + }) + + socket.once('close', () => { + // 传入 true 表示这是初始连接的断开 + renderer.reconnect(true) + }) + + socket.once('error', (error) => { + logger.error(`[render][WebSocket] 连接错误: ${error.message}`) + socket.close() }) })) }