From 8f61e213df62a3e84b87074d3ff5462f455c1c34 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 26 Apr 2025 01:37:20 +0800 Subject: [PATCH] =?UTF-8?q?ws=E5=AE=A2=E6=88=B7=E7=AB=AF=EF=BC=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/default.json | 9 ++- lib/config/configControl.js | 2 +- lib/system/init.js | 2 + models/ws/wsClient.js | 108 ++++++++++++++++++++++++++++++++++++ package.json | 3 +- 5 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 models/ws/wsClient.js diff --git a/config/default.json b/config/default.json index f3eebb5..a346796 100644 --- a/config/default.json +++ b/config/default.json @@ -1,6 +1,13 @@ { "debug": true, "core": true, + "coreConfig": { + "coreUrl": "", + "wsUrl": "", + "wsClientId": "", + "wsSecret": "", + "wsReConnectInterval": "5000" + }, "mode": "deepseek", "modelType": "deepseek-ai/DeepSeek-V3", "historyLength": 3, @@ -23,4 +30,4 @@ ] }, "maxMessageLength": 100 -} \ No newline at end of file +} diff --git a/lib/config/configControl.js b/lib/config/configControl.js index ec1f815..866d172 100644 --- a/lib/config/configControl.js +++ b/lib/config/configControl.js @@ -37,7 +37,7 @@ function init() { lastModified = stats.mtimeMs; if (configCache.debug) { - logger.info('crystelf-plugin 日志模块初始化成功..'); + logger.info('crystelf-plugin 配置模块初始化成功..'); } } catch (err) { logger.warn('crystelf-plugin 初始化配置失败,使用空配置..', err); diff --git a/lib/system/init.js b/lib/system/init.js index 74bd5c8..34378d3 100644 --- a/lib/system/init.js +++ b/lib/system/init.js @@ -1,8 +1,10 @@ import configControl from '../config/configControl.js'; +import wsClient from '../../models/ws/wsClient.js'; export const crystelfInit = { async CSH() { await configControl.init(); + await wsClient.initialize(); logger.mark('crystelf 完成初始化'); }, }; diff --git a/models/ws/wsClient.js b/models/ws/wsClient.js new file mode 100644 index 0000000..1565e24 --- /dev/null +++ b/models/ws/wsClient.js @@ -0,0 +1,108 @@ +import WebSocket from 'ws'; +import configControl from '../../lib/config/configControl.js'; + +class WsClient { + constructor() { + this.ws = null; + this.wsURL = null; + this.secret = null; + this.clientId = null; + this.reconnectInterval = null; + this.isReconnecting = false; + } + + async initialize() { + try { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + logger.mark('crystelf WS 客户端已连接..'); + return; + } + + this.wsURL = configControl.get('coreConfig')?.wsUrl; + this.secret = configControl.get('coreConfig')?.wsSecret; + this.clientId = configControl.get('coreConfig')?.wsClientId; + this.reconnectInterval = configControl.get('coreConfig')?.wsReConnectInterval; + + logger.info(this.wsURL); + this.ws = new WebSocket(this.wsURL); + + this.ws.on('open', () => { + logger.mark('crystelf WS 客户端连接成功..'); + this.authenticate(); + }); + + this.ws.on('message', (raw) => { + try { + const data = JSON.parse(raw); + this.handleMessage(data); + } catch (err) { + logger.err(err); + } + }); + + this.ws.on('error', (err) => { + logger.error('WS 连接错误:', err); + }); + + this.ws.on('close', (code, reason) => { + logger.warn(`crystelf WS 客户端连接断开:${code} - ${reason}`); + this.reconnect(); + }); + } catch (err) { + logger.error(err); + } + } + + async authenticate() { + const authMsg = { + type: 'auth', + secret: this.secret, + clientId: this.clientId, + }; + await this.sendMessage(authMsg); + } + + async sendMessage(msg) { + if (this.ws?.readyState === WebSocket.OPEN) { + this.ws.send(JSON.stringify(msg)); + } else { + logger.warn('crystelf WS 服务器未连接,无法发送消息..'); + } + } + + async handleMessage(msg) { + switch (msg.type) { + case 'auth': + if (msg.success) { + logger.mark('crystelf WS 认证成功..'); + } else { + logger.error('crystelf WS 认证失败,关闭连接..'); + this.ws.close(4001, '认证失败'); + } + break; + case 'ping': + await this.sendMessage({ type: 'pong' }); + break; + case 'message': + logger.mark(`服务端消息: ${msg.data}`); + break; + default: + logger.warn(`未知消息类型: ${msg.type}`); + } + } + + async reconnect() { + if (this.isReconnecting) return; + this.isReconnecting = true; + + logger.mark('crystelf WS 客户端尝试重连..'); + setTimeout(() => { + this.isReconnecting = false; + this.initialize(); + }, this.reconnectInterval); + } +} + +const wsClient = new WsClient(); + +export default wsClient; diff --git a/package.json b/package.json index fe0dbd4..e2f9ee2 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "dependencies": { "axios": "^1.8.4", "chalk": "^5.4.1", - "openai": "^4.89.0" + "openai": "^4.89.0", + "ws": "^8.18.1" }, "imports": {}, "devDependencies": {