From 4a82585c29aa606b65335c8163c13ce4fcac6f35 Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 17 Apr 2025 13:36:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B3=E9=97=AD=E6=9C=AA=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E7=9A=84WebSocket=E8=BF=9E=E6=8E=A5=E5=B9=B6=E9=87=8D=E6=9E=84?= =?UTF-8?q?Redis=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在WebSocket认证失败时,主动关闭连接以提高安全性。重构了Redis服务中的方法,使其更加通用,并更新了相关的导入和调用。同时,调整了数据持久化路径的生成方式,支持自定义文件名。 --- src/services/redis/redis.ts | 76 +++++++++++----------------------- src/services/ws/wsServer.ts | 1 + src/utils/redis/persistence.ts | 16 ++++--- 3 files changed, 36 insertions(+), 57 deletions(-) diff --git a/src/services/redis/redis.ts b/src/services/redis/redis.ts index e89aebe..e2861dc 100644 --- a/src/services/redis/redis.ts +++ b/src/services/redis/redis.ts @@ -2,9 +2,9 @@ import Redis from 'ioredis'; import logger from '../../utils/core/logger'; import tools from '../../utils/core/tool'; import config from '../../utils/core/config'; -import redisTool from '../../utils/redis/redisTools'; -import IUser from '../../types/user'; +import redisTools from '../../utils/redis/redisTools'; import Persistence from '../../utils/redis/persistence'; +import IUser from '../../types/user'; class RedisService { private client!: Redis; @@ -93,7 +93,7 @@ class RedisService { } public async setObject(key: string, value: T, ttl?: number): Promise { - const serialized = redisTool.serialize(value); + const serialized = redisTools.serialize(value); await this.getClient().set(key, serialized); if (ttl) { @@ -105,66 +105,40 @@ class RedisService { const serialized = await this.getClient().get(key); if (!serialized) return undefined; - const deserialized = redisTool.deserialize(serialized); - return redisTool.reviveDates(deserialized); + const deseralized = redisTools.deserialize(serialized); + return redisTools.reviveDates(deseralized); } - public async updateUser(qq: string, updates: Partial): Promise { - const existing = await this.getObject(`user:${qq}`); + public async update(key: string, updates: T): Promise { + const existing = await this.getObject(key); if (!existing) { - throw new Error(`用户 ${qq} 不存在`); + logger.error(`数据${key}不存在..`); } - const updatedUser = { ...existing, ...updates, updatedAt: new Date() }; - await this.persistUser(updatedUser); - return updatedUser; + const updated = { ...existing, ...updates }; + await this.setObject(key, updated); + return updated; } - public async persistUser(user: T): Promise { - try { - await Promise.all([ - this.setObject(`user:${user.qq}`, user), - Persistence.writeDataLocal(user.name, user), - ]); - } catch (err) { - logger.error(err); - throw err; + public async fetch(key: string, fileName: string): Promise { + const data = await this.getObject(key); + if (data) return data; + const fromLocal = await Persistence.readDataLocal(key, fileName); + if (fromLocal) { + await this.setObject(key, fromLocal); + return fromLocal; } + logger.error(`数据${key}不存在..`); } - public async fetchUser( - qq: string, - username: string - ): Promise { - try { - const fromRedis = await this.getObject(`user:${qq}`); - if (fromRedis) return fromRedis; - - const fromLocal = await Persistence.readDataLocal(username); - if (fromLocal) { - await this.setObject(`user:${qq}`, fromLocal); - return fromLocal; - } - - logger.error(`用户${username},qq${qq}不存在!`); - return undefined; - } catch (err) { - logger.error(err); - throw err; - } + public async persistData(key: string, data: T, fileName: string): Promise { + await this.setObject(key, data); + await Persistence.writeDataLocal(key, data, fileName); + return; } public async test(): Promise { - const testData: IUser = { - name: 'Jerry', - qq: '114514', - isAdmin: true, - password: '114514', - createdAt: new Date(), - }; - - await this.persistUser(testData); - const user = await this.fetchUser('114514', 'Jerry'); - logger.debug(user); + const user = await this.fetch('Jerry', 'IUser'); + logger.debug('User:', user); } } diff --git a/src/services/ws/wsServer.ts b/src/services/ws/wsServer.ts index 09dc131..965bb10 100644 --- a/src/services/ws/wsServer.ts +++ b/src/services/ws/wsServer.ts @@ -83,6 +83,7 @@ class WSServer { } else { logger.warn(`Auth failed from ${ip} (invalid secret), clientId: ${msg.clientId}`); await WsTools.send(socket, { type: 'auth', success: false }); + socket.close(4001, 'Authentication failed'); } } diff --git a/src/utils/redis/persistence.ts b/src/utils/redis/persistence.ts index d3e76c9..d1b0ad6 100644 --- a/src/utils/redis/persistence.ts +++ b/src/utils/redis/persistence.ts @@ -5,8 +5,8 @@ import logger from '../core/logger'; import fs from 'fs/promises'; class Persistence { - private static getUserDataPath(username: string): string { - return path.join(paths.get('userData'), username, 'data.json'); + private static getUserDataPath(username: string, fileName: string): string { + return path.join(paths.get('userData'), username, `${fileName}.json`); } private static async ensureUserPath(username: string): Promise { @@ -18,9 +18,13 @@ class Persistence { } } - public static async writeDataLocal(username: string, data: T): Promise { + public static async writeDataLocal( + username: string, + data: T, + fileName: string + ): Promise { await this.ensureUserPath(username); - const filePath = this.getUserDataPath(username); + const filePath = this.getUserDataPath(username, fileName); try { await fs.writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8'); @@ -30,8 +34,8 @@ class Persistence { } } - public static async readDataLocal(username: string): Promise { - const filePath = this.getUserDataPath(username); + public static async readDataLocal(username: string, fileName: string): Promise { + const filePath = this.getUserDataPath(username, fileName); try { const data = await fs.readFile(filePath, 'utf-8');