Files
whale-town-end/src/business/zulip
moyin d92a078fc7 refactor:将 ZulipAccountsModule 改为全局单例模块
- 在 AppModule 中统一导入 ZulipAccountsModule.forRoot()
- 移除 admin.module、auth.module、zulip.module 中的重复导入
- 添加数据库 charset: utf8mb4 配置,支持中文和 emoji
2026-01-15 14:58:28 +08:00
..

Zulip 业务模块

Zulip业务模块是游戏服务器与Zulip聊天系统集成的核心业务层负责处理Zulip账号关联管理和事件处理的业务逻辑实现游戏内聊天消息与Zulip平台的双向同步。

对外提供的接口

ZulipAccountsBusinessService

create(createDto: CreateZulipAccountDto): Promise

创建游戏用户与Zulip账号的关联关系支持数据验证和唯一性检查。

findByGameUserId(gameUserId: string, includeGameUser?: boolean): Promise<ZulipAccountResponseDto | null>

根据游戏用户ID查找对应的Zulip账号关联信息支持缓存优化。

getStatusStatistics(): Promise

获取所有Zulip账号关联的状态统计信息包括活跃、非活跃、暂停、错误状态的数量。

ZulipEventProcessorService

startEventProcessing(): Promise

启动Zulip事件处理循环监听所有活跃的事件队列。

stopEventProcessing(): Promise

停止事件处理循环,清理所有事件队列资源。

registerEventQueue(queueId: string, userId: string, lastEventId?: number): Promise

注册新的Zulip事件队列到处理列表中。

unregisterEventQueue(queueId: string): Promise

从处理列表中注销指定的事件队列。

setMessageDistributor(distributor: MessageDistributor): void

设置消息分发器,用于向游戏客户端发送消息。

processMessageEvent(event: ZulipEvent, senderUserId: string): Promise

处理Zulip消息事件转换格式后分发给相关的游戏客户端。

convertMessageFormat(zulipMessage: ZulipMessage, streamName?: string): Promise

将Zulip消息转换为游戏协议格式chat_render

determineTargetPlayers(message: ZulipMessage, streamName: string, senderUserId: string): Promise<string[]>

根据消息的Stream确定应该接收消息的玩家空间过滤

distributeMessage(gameMessage: GameMessage, targetPlayers: string[]): Promise

通过WebSocket将消息发送给目标客户端。

broadcastToMap(mapId: string, gameMessage: GameMessage): Promise

向指定地图区域内的所有在线玩家广播消息。

getProcessingStats(): EventProcessingStats

获取事件处理的统计信息,包括活跃队列数、处理事件数等。

使用的项目内部依赖

ISessionQueryService (来自 core/session_core)

会话查询接口,用于获取地图中的在线玩家和会话信息,实现空间过滤功能。

IZulipConfigService (来自 core/zulip_core)

Zulip配置服务接口用于获取Stream与地图的映射关系。

IZulipClientPoolService (来自 core/zulip_core)

Zulip客户端池服务接口用于获取用户的Zulip客户端实例。

ZulipAccountsRepository (来自 core/db/zulip_accounts)

Zulip账号数据仓库提供账号关联的CRUD操作。

AppLoggerService (来自 core/utils/logger)

日志服务,用于记录业务操作和系统事件。

Cache (来自 @nestjs/cache-manager)

缓存管理器,用于缓存账号查询结果和统计数据,提升查询性能。

CreateZulipAccountDto, ZulipAccountResponseDto (来自 core/db/zulip_accounts)

数据传输对象,定义账号创建和响应的数据结构。

核心特性

事件队列轮询机制

  • 支持多用户并发事件队列管理
  • 2秒轮询间隔非阻塞模式获取事件
  • 自动处理队列错误和重连机制
  • 支持队列的动态注册和注销

消息格式转换

  • Zulip消息到游戏协议chat_render的自动转换
  • Markdown格式移除保留纯文本内容
  • HTML标签清理和实体解码
  • 消息长度限制200字符和截断处理

空间过滤机制

  • 根据Zulip Stream确定对应的游戏地图
  • 从SessionManager获取地图内的在线玩家
  • 自动排除消息发送者,避免收到自己的消息
  • 支持区域广播功能

缓存优化

  • 账号查询结果缓存5分钟TTL
  • 统计数据缓存1分钟TTL
  • 自动缓存失效和更新机制
  • 缓存键前缀隔离

性能监控

  • 操作耗时记录和日志输出
  • 事件处理统计(处理事件数、消息数)
  • 队列状态监控(活跃队列数、总队列数)
  • 最后事件时间追踪

潜在风险

事件队列连接风险

  • Zulip服务器不可用时事件队列无法获取
  • 队列ID过期导致BAD_EVENT_QUEUE_ID错误
  • 网络不稳定时轮询失败
  • 缓解措施:自动禁用错误队列、支持队列重新激活、错误日志记录

消息分发延迟风险

  • 大量并发消息可能导致分发延迟
  • WebSocket连接断开时消息丢失
  • 目标玩家列表过大时性能下降
  • 缓解措施:异步分发、连接状态检查、分批发送

缓存一致性风险

  • 缓存数据与数据库不一致
  • 缓存清理失败导致脏数据
  • 高并发下缓存穿透
  • 缓解措施写操作后主动清理缓存、缓存失败降级查询、合理设置TTL

内存泄漏风险

  • 事件队列未正确注销导致内存累积
  • 长时间运行后统计数据累积
  • 缓解措施:模块销毁时清理资源、提供统计重置接口

架构定位

  • 层级: Business层业务层
  • 职责: 业务逻辑处理、服务协调
  • 依赖: Core层的ZulipCoreModule、ZulipAccountsModule等

文件结构

src/business/zulip/
├── services/
│   ├── zulip_accounts_business.service.ts    # Zulip账号业务服务
│   ├── zulip_accounts_business.service.spec.ts
│   ├── zulip_event_processor.service.ts      # Zulip事件处理服务
│   └── zulip_event_processor.service.spec.ts
├── zulip.module.ts                           # 业务模块定义
├── zulip.module.spec.ts                      # 模块测试
└── README.md                                 # 本文档

依赖关系

ZulipModule (Business层)
  ├─ imports: ZulipCoreModule (Core层)
  ├─ imports: ZulipAccountsModule (Core层)
  ├─ imports: RedisModule (Core层)
  ├─ imports: LoggerModule (Core层)
  ├─ imports: LoginCoreModule (Core层)
  ├─ imports: AuthModule (Business层)
  ├─ imports: ChatModule (Business层)
  ├─ providers: [ZulipEventProcessorService, ZulipAccountsBusinessService]
  └─ exports: [ZulipEventProcessorService, ZulipAccountsBusinessService, DynamicConfigManagerService]

架构规范

Business层职责

  • 业务逻辑实现
  • 服务协调和编排
  • 业务规则验证
  • 调用Core层服务

Business层禁止

  • 包含HTTP协议处理Controller应在Gateway层
  • 直接访问数据库应通过Core层Repository
  • 包含技术实现细节

迁移说明

2026-01-14 架构优化

Controller迁移到Gateway层

所有Controller已从本模块迁移到 src/gateway/zulip/

  • DynamicConfigController -> src/gateway/zulip/dynamic_config.controller.ts
  • WebSocketDocsController -> src/gateway/zulip/websocket_docs.controller.ts
  • WebSocketOpenApiController -> src/gateway/zulip/websocket_openapi.controller.ts
  • WebSocketTestController -> src/gateway/zulip/websocket_test.controller.ts
  • ZulipAccountsController -> src/gateway/zulip/zulip_accounts.controller.ts

原因符合四层架构规范Controller属于Gateway层HTTP协议处理不应在Business层。

相关文档

最近更新

  • 2026-01-14: 功能文档完善 - 补充对外接口、内部依赖、核心特性、潜在风险章节 (moyin)
  • 2026-01-14: 架构优化 - Controller迁移到Gateway层 (moyin)
  • 2026-01-14: 聊天功能迁移到business/chat模块 (moyin)

维护者

  • angjustinl
  • moyin