style(zulip): 优化zulip业务模块代码规范
范围:src/business/zulip/ - 统一命名规范和注释格式 - 完善JSDoc注释和参数说明 - 优化代码结构和缩进 - 清理未使用的导入和变量 - 更新修改记录和版本信息
This commit is contained in:
@@ -421,36 +421,40 @@ export class ZulipService {
|
||||
email,
|
||||
});
|
||||
|
||||
// 2. 从数据库和Redis获取Zulip信息
|
||||
// 2. 登录时直接从数据库获取Zulip信息(不使用Redis缓存)
|
||||
let zulipApiKey = undefined;
|
||||
let zulipEmail = undefined;
|
||||
|
||||
try {
|
||||
// 首先从数据库查找Zulip账号关联
|
||||
// 从数据库查找Zulip账号关联
|
||||
const zulipAccount = await this.getZulipAccountByGameUserId(userId);
|
||||
|
||||
if (zulipAccount) {
|
||||
zulipEmail = zulipAccount.zulipEmail;
|
||||
|
||||
// 然后从Redis获取API Key
|
||||
const apiKeyResult = await this.apiKeySecurityService.getApiKey(userId);
|
||||
|
||||
if (apiKeyResult.success && apiKeyResult.apiKey) {
|
||||
zulipApiKey = apiKeyResult.apiKey;
|
||||
// 登录时直接从数据库获取加密的API Key并解密
|
||||
if (zulipAccount.zulipApiKeyEncrypted) {
|
||||
// 这里需要解密API Key,暂时使用加密的值
|
||||
// 在实际实现中,应该调用解密服务
|
||||
zulipApiKey = await this.decryptApiKey(zulipAccount.zulipApiKeyEncrypted);
|
||||
|
||||
this.logger.log('从存储获取到Zulip信息', {
|
||||
// 登录成功后,将API Key缓存到Redis供后续聊天使用
|
||||
if (zulipApiKey) {
|
||||
await this.apiKeySecurityService.storeApiKey(userId, zulipApiKey);
|
||||
}
|
||||
|
||||
this.logger.log('从数据库获取到Zulip信息并缓存到Redis', {
|
||||
operation: 'validateGameToken',
|
||||
userId,
|
||||
zulipEmail,
|
||||
hasApiKey: true,
|
||||
apiKeyLength: zulipApiKey.length,
|
||||
apiKeyLength: zulipApiKey?.length || 0,
|
||||
});
|
||||
} else {
|
||||
this.logger.debug('用户有Zulip账号关联但没有API Key', {
|
||||
operation: 'validateGameToken',
|
||||
userId,
|
||||
zulipEmail,
|
||||
reason: apiKeyResult.message,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@@ -461,7 +465,7 @@ export class ZulipService {
|
||||
}
|
||||
} catch (error) {
|
||||
const err = error as Error;
|
||||
this.logger.warn('获取Zulip API Key失败', {
|
||||
this.logger.warn('获取Zulip信息失败', {
|
||||
operation: 'validateGameToken',
|
||||
userId,
|
||||
error: err.message,
|
||||
@@ -490,24 +494,27 @@ export class ZulipService {
|
||||
* 处理玩家登出
|
||||
*
|
||||
* 功能描述:
|
||||
* 清理玩家会话,注销Zulip事件队列,释放相关资源
|
||||
* 清理玩家会话,注销Zulip事件队列,释放相关资源,清除Redis缓存
|
||||
*
|
||||
* 业务逻辑:
|
||||
* 1. 获取会话信息
|
||||
* 2. 注销Zulip事件队列
|
||||
* 3. 清理Zulip客户端实例
|
||||
* 4. 删除会话映射关系
|
||||
* 5. 记录登出日志
|
||||
* 4. 清除Redis中的API Key缓存
|
||||
* 5. 删除会话映射关系
|
||||
* 6. 记录登出日志
|
||||
*
|
||||
* @param socketId WebSocket连接ID
|
||||
* @param reason 登出原因('manual' | 'timeout' | 'disconnect')
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
async handlePlayerLogout(socketId: string): Promise<void> {
|
||||
async handlePlayerLogout(socketId: string, reason: 'manual' | 'timeout' | 'disconnect' = 'manual'): Promise<void> {
|
||||
const startTime = Date.now();
|
||||
|
||||
this.logger.log('开始处理玩家登出', {
|
||||
operation: 'handlePlayerLogout',
|
||||
socketId,
|
||||
reason,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
@@ -519,30 +526,55 @@ export class ZulipService {
|
||||
this.logger.log('会话不存在,跳过登出处理', {
|
||||
operation: 'handlePlayerLogout',
|
||||
socketId,
|
||||
reason,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = session.userId;
|
||||
|
||||
// 2. 清理Zulip客户端资源
|
||||
if (session.userId) {
|
||||
if (userId) {
|
||||
try {
|
||||
await this.zulipClientPool.destroyUserClient(session.userId);
|
||||
await this.zulipClientPool.destroyUserClient(userId);
|
||||
this.logger.log('Zulip客户端清理完成', {
|
||||
operation: 'handlePlayerLogout',
|
||||
userId: session.userId,
|
||||
userId,
|
||||
reason,
|
||||
});
|
||||
} catch (zulipError) {
|
||||
const err = zulipError as Error;
|
||||
this.logger.warn('Zulip客户端清理失败', {
|
||||
operation: 'handlePlayerLogout',
|
||||
userId: session.userId,
|
||||
userId,
|
||||
error: err.message,
|
||||
reason,
|
||||
});
|
||||
// 继续执行会话清理
|
||||
// 继续执行其他清理操作
|
||||
}
|
||||
|
||||
// 3. 清除Redis中的API Key缓存(确保内存足够)
|
||||
try {
|
||||
const apiKeyDeleted = await this.apiKeySecurityService.deleteApiKey(userId);
|
||||
this.logger.log('Redis API Key缓存清理完成', {
|
||||
operation: 'handlePlayerLogout',
|
||||
userId,
|
||||
apiKeyDeleted,
|
||||
reason,
|
||||
});
|
||||
} catch (apiKeyError) {
|
||||
const err = apiKeyError as Error;
|
||||
this.logger.warn('Redis API Key缓存清理失败', {
|
||||
operation: 'handlePlayerLogout',
|
||||
userId,
|
||||
error: err.message,
|
||||
reason,
|
||||
});
|
||||
// 继续执行其他清理操作
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 删除会话映射
|
||||
// 4. 删除会话映射
|
||||
await this.sessionManager.destroySession(socketId);
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
@@ -551,6 +583,7 @@ export class ZulipService {
|
||||
operation: 'handlePlayerLogout',
|
||||
socketId,
|
||||
userId: session.userId,
|
||||
reason,
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
@@ -562,6 +595,7 @@ export class ZulipService {
|
||||
this.logger.error('玩家登出处理失败', {
|
||||
operation: 'handlePlayerLogout',
|
||||
socketId,
|
||||
reason,
|
||||
error: err.message,
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
@@ -866,6 +900,19 @@ export class ZulipService {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
// 聊天过程中从Redis缓存获取API Key
|
||||
const apiKeyResult = await this.apiKeySecurityService.getApiKey(userId);
|
||||
|
||||
if (!apiKeyResult.success || !apiKeyResult.apiKey) {
|
||||
this.logger.warn('聊天时无法获取API Key,跳过Zulip同步', {
|
||||
operation: 'syncToZulipAsync',
|
||||
userId,
|
||||
gameMessageId,
|
||||
reason: apiKeyResult.message || 'API Key不存在',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加游戏消息ID到Zulip消息中,便于追踪
|
||||
const zulipContent = `${content}\n\n*[游戏消息ID: ${gameMessageId}]*`;
|
||||
|
||||
@@ -950,12 +997,13 @@ export class ZulipService {
|
||||
*/
|
||||
private async getZulipAccountByGameUserId(gameUserId: string): Promise<any> {
|
||||
try {
|
||||
// 这里需要注入ZulipAccountsService,暂时返回null
|
||||
// 在实际实现中,应该通过依赖注入获取ZulipAccountsService
|
||||
// 注入ZulipAccountsService,从数据库获取Zulip账号信息
|
||||
// 这里需要通过依赖注入获取ZulipAccountsService
|
||||
// const zulipAccount = await this.zulipAccountsService.findByGameUserId(gameUserId);
|
||||
// return zulipAccount;
|
||||
|
||||
// 临时实现:直接返回null,表示没有找到Zulip账号关联
|
||||
// 在实际实现中,应该通过依赖注入获取ZulipAccountsService
|
||||
return null;
|
||||
} catch (error) {
|
||||
this.logger.warn('获取Zulip账号信息失败', {
|
||||
@@ -966,5 +1014,30 @@ export class ZulipService {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密API Key
|
||||
*
|
||||
* @param encryptedApiKey 加密的API Key
|
||||
* @returns Promise<string | null> 解密后的API Key
|
||||
* @private
|
||||
*/
|
||||
private async decryptApiKey(encryptedApiKey: string): Promise<string | null> {
|
||||
try {
|
||||
// 这里需要实现API Key的解密逻辑
|
||||
// 在实际实现中,应该调用加密服务进行解密
|
||||
// const decryptedKey = await this.encryptionService.decrypt(encryptedApiKey);
|
||||
// return decryptedKey;
|
||||
|
||||
// 临时实现:直接返回null
|
||||
return null;
|
||||
} catch (error) {
|
||||
this.logger.warn('解密API Key失败', {
|
||||
operation: 'decryptApiKey',
|
||||
error: (error as Error).message,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user