Files
whale-town-end/src/business/zulip
moyin 3733717d1f feat: 添加JWT令牌刷新功能
- 新增 @nestjs/jwt 和 jsonwebtoken 依赖包
- 实现 refreshAccessToken 方法支持令牌续期
- 添加 RefreshTokenDto 和 RefreshTokenResponseDto
- 新增 /auth/refresh-token 接口
- 完善令牌刷新的限流和超时控制
- 增加相关单元测试覆盖
- 优化错误处理和日志记录
2026-01-06 16:48:24 +08:00
..

Zulip集成业务模块

架构重构说明

本模块已按照项目的分层架构要求进行重构,将技术实现细节移动到核心服务层,业务逻辑保留在业务层。

重构前后对比

重构前( 违反架构原则)

src/business/zulip/services/
├── zulip_client.service.ts          # 技术实现API调用
├── zulip_client_pool.service.ts     # 技术实现:连接池管理
├── config_manager.service.ts        # 技术实现:配置管理
├── zulip_event_processor.service.ts # 技术实现:事件处理
├── session_manager.service.ts       # ✅ 业务逻辑:会话管理
└── message_filter.service.ts        # ✅ 业务逻辑:消息过滤

重构后( 符合架构原则)

# 业务逻辑层
src/business/zulip/
├── zulip.service.ts                 # 业务协调服务
├── zulip_websocket.gateway.ts       # WebSocket业务网关
└── services/
    ├── session_manager.service.ts   # 会话业务逻辑
    └── message_filter.service.ts    # 消息过滤业务规则

# 核心服务层
src/core/zulip/
├── interfaces/
│   └── zulip-core.interfaces.ts     # 核心服务接口定义
├── services/
│   ├── zulip_client.service.ts      # Zulip API封装
│   ├── zulip_client_pool.service.ts # 客户端池管理
│   ├── config_manager.service.ts    # 配置管理
│   ├── zulip_event_processor.service.ts # 事件处理
│   └── ...                          # 其他技术服务
└── zulip-core.module.ts             # 核心服务模块

架构优势

1. 单一职责原则

  • 业务层:只关注游戏相关的业务逻辑和规则
  • 核心层只处理技术实现和第三方API调用

2. 依赖注入和接口抽象

// 业务层通过接口依赖核心服务
constructor(
  @Inject('ZULIP_CLIENT_POOL_SERVICE')
  private readonly zulipClientPool: IZulipClientPoolService,
  @Inject('ZULIP_CONFIG_SERVICE')
  private readonly configManager: IZulipConfigService,
) {}

3. 易于测试和维护

  • 业务逻辑可以独立测试,不依赖具体的技术实现
  • 核心服务可以独立替换,不影响业务逻辑
  • 接口定义清晰,便于理解和维护

服务职责划分

业务逻辑层服务

服务 职责 业务价值
ZulipService 游戏登录/登出业务流程协调 处理玩家生命周期管理
SessionManagerService 游戏会话状态和上下文管理 维护玩家位置和聊天上下文
MessageFilterService 消息过滤和业务规则控制 实现内容审核和权限验证
ZulipWebSocketGateway WebSocket业务协议处理 游戏协议转换和路由

核心服务层服务

服务 职责 技术价值
ZulipClientService Zulip REST API封装 第三方API调用抽象
ZulipClientPoolService 客户端连接池管理 资源管理和性能优化
ConfigManagerService 配置文件管理和热重载 系统配置和运维支持
ZulipEventProcessorService 事件队列处理和消息转换 异步消息处理机制

使用示例

业务层调用核心服务

@Injectable()
export class ZulipService {
  constructor(
    @Inject('ZULIP_CLIENT_POOL_SERVICE')
    private readonly zulipClientPool: IZulipClientPoolService,
  ) {}

  async sendChatMessage(request: ChatMessageRequest): Promise<ChatMessageResponse> {
    // 业务逻辑:验证和处理
    const session = await this.sessionManager.getSession(request.socketId);
    const context = await this.sessionManager.injectContext(request.socketId);
    
    // 调用核心服务:技术实现
    const result = await this.zulipClientPool.sendMessage(
      session.userId,
      context.stream,
      context.topic,
      request.content,
    );
    
    return { success: result.success, messageId: result.messageId };
  }
}

迁移指南

如果你的代码中直接导入了已移动的服务,请按以下方式更新:

更新导入路径

// ❌ 旧的导入方式
import { ZulipClientPoolService } from './services/zulip_client_pool.service';

// ✅ 新的导入方式(通过依赖注入)
import { IZulipClientPoolService } from '../../core/zulip/interfaces/zulip-core.interfaces';

constructor(
  @Inject('ZULIP_CLIENT_POOL_SERVICE')
  private readonly zulipClientPool: IZulipClientPoolService,
) {}

更新模块导入

// ✅ 业务模块自动导入核心模块
@Module({
  imports: [
    ZulipCoreModule, // 自动提供所有核心服务
    // ...
  ],
})
export class ZulipModule {}

测试策略

业务逻辑测试

// 使用Mock核心服务测试业务逻辑
const mockZulipClientPool: IZulipClientPoolService = {
  sendMessage: jest.fn().mockResolvedValue({ success: true }),
  // ...
};

const module = await Test.createTestingModule({
  providers: [
    ZulipService,
    { provide: 'ZULIP_CLIENT_POOL_SERVICE', useValue: mockZulipClientPool },
  ],
}).compile();

核心服务测试

// 独立测试技术实现
describe('ZulipClientService', () => {
  it('should call Zulip API correctly', async () => {
    // 测试API调用逻辑
  });
});

这种架构设计确保了业务逻辑与技术实现的清晰分离,提高了代码的可维护性和可测试性。