Files
whale-town-end/src/business/zulip
moyin f5eda2ea34 docs(zulip): 完善zulip业务模块文档
范围:src/business/zulip/README.md
- 添加完整的WebSocket事件接口文档
- 包含所有事件的输入输出格式说明
- 更新版本信息和修改记录
- 完善使用示例和注意事项
2026-01-12 19:43:14 +08:00
..

Zulip 游戏集成业务模块

Zulip 是游戏与Zulip社群平台的集成业务模块提供完整的实时聊天、会话管理、消息过滤和WebSocket通信功能实现游戏内聊天与Zulip社群的双向同步支持基于位置的聊天上下文管理和业务规则驱动的消息过滤控制。

玩家登录和会话管理

handlePlayerLogin()

验证游戏Token创建Zulip客户端建立会话映射关系支持JWT认证和API Key获取。

handlePlayerLogout()

清理玩家会话注销Zulip事件队列释放相关资源确保连接正常断开。

getSession()

根据socketId获取会话信息并更新最后活动时间支持会话状态查询。

getSocketsInMap()

获取指定地图中所有在线玩家的Socket ID列表用于消息分发和空间过滤。

消息发送和处理

sendChatMessage()

处理游戏客户端发送的聊天消息转发到对应的Zulip Stream/Topic包含内容过滤和权限验证。

processZulipMessage()

处理Zulip事件队列推送的消息转换格式后发送给相关的游戏客户端实现双向通信。

updatePlayerPosition()

更新玩家在游戏世界中的位置信息,用于消息路由和上下文注入,支持地图切换。

WebSocket网关功能

handleConnection()

处理游戏客户端WebSocket连接建立记录连接信息并初始化连接状态。

handleDisconnect()

处理游戏客户端连接断开,清理相关资源并执行登出逻辑。

handleLogin()

处理登录消息验证Token并建立会话返回登录结果和用户信息。

handleChat()

处理聊天消息,验证用户认证状态和消息格式,调用业务服务发送消息。

sendChatRender()

向指定客户端发送聊天渲染消息,用于显示气泡或聊天框。

broadcastToMap()

向指定地图的所有客户端广播消息,支持区域性消息分发。

会话管理功能

createSession()

创建会话并绑定Socket_ID与Zulip_Queue_ID建立WebSocket连接与Zulip队列的映射关系。

injectContext()

上下文注入根据玩家位置确定消息应该发送到的Zulip Stream和Topic。

destroySession()

清理玩家会话数据,从地图玩家列表中移除,释放相关资源。

cleanupExpiredSessions()

定时清理超时的会话数据和相关资源返回需要注销的Zulip队列ID列表。

消息过滤和安全

validateMessage()

对消息进行综合验证,包括内容过滤、频率限制和权限验证。

filterContent()

检查消息内容是否包含敏感词,进行内容过滤和替换。

checkRateLimit()

检查用户是否超过消息发送频率限制,防止刷屏。

validatePermission()

验证用户是否有权限向目标Stream发送消息防止位置欺诈。

logViolation()

记录用户的违规行为,用于监控和分析。

WebSocket事件接口

'login'

客户端登录认证建立游戏会话并获取Zulip访问权限。

  • 输入: { type: 'login', token: string }
  • 输出: { t: 'login_success', sessionId: string, userId: string, username: string, currentMap: string }{ t: 'login_error', message: string }

'logout'

客户端主动登出,清理会话资源并断开连接。

  • 输入: { type: 'logout' }
  • 输出: { t: 'logout_success', message: string }

'chat'

发送聊天消息支持本地和全局范围自动同步到Zulip。

  • 输入: { type: 'chat', content: string, scope?: 'local'|'global' }
  • 输出: { t: 'chat_sent', messageId: string, message: string }{ t: 'chat_error', message: string }

'position'

更新玩家位置信息,支持地图切换和位置广播。

  • 输入: { type: 'position', x: number, y: number, mapId: string }
  • 输出: 广播给同地图其他玩家 { t: 'position_update', userId: string, username: string, x: number, y: number, mapId: string }

'chat_render'

接收聊天消息渲染事件,用于显示其他玩家的聊天内容。

  • 输入: 无(服务器推送)
  • 输出: { t: 'chat_render', userId: string, username: string, content: string, timestamp: number, mapId: string }

'connected'

连接建立确认事件,服务器主动发送连接状态。

  • 输入: 无(服务器推送)
  • 输出: { type: 'connected', message: string, socketId: string }

'error'

错误事件通知,用于处理各种异常情况和错误信息。

  • 输入: 无(服务器推送)
  • 输出: { type: 'error', message: string }

REST API接口

sendMessage()

通过REST API发送聊天消息到Zulip推荐使用WebSocket接口

getChatHistory()

获取指定地图或全局的聊天历史记录,支持分页查询。

getSystemStatus()

获取WebSocket连接状态、Zulip集成状态等系统信息。

getWebSocketInfo()

获取WebSocket连接的详细信息包括连接地址、协议等。

使用的项目内部依赖

ZulipCoreModule (来自 core/zulip_core)

提供Zulip核心技术服务包括客户端池管理、配置管理和事件处理等底层技术实现。

LoginCoreModule (来自 core/login_core)

提供用户认证和Token验证服务支持JWT令牌验证和用户信息获取。

RedisModule (来自 core/redis)

提供会话状态缓存和数据存储服务,支持会话持久化和快速查询。

LoggerModule (来自 core/utils/logger)

提供统一的日志记录服务,支持结构化日志和性能监控。

ZulipAccountsModule (来自 core/db/zulip_accounts)

提供Zulip账号关联管理功能支持用户与Zulip账号的绑定关系。

AuthModule (来自 business/auth)

提供JWT验证和用户认证服务支持用户身份验证和权限控制。

IZulipClientPoolService (来自 core/zulip_core/interfaces)

Zulip客户端池服务接口用于管理用户专用的Zulip客户端实例。

IZulipConfigService (来自 core/zulip_core/interfaces)

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

ApiKeySecurityService (来自 core/zulip_core/services)

API密钥安全服务用于获取和管理用户的Zulip API Key。

IRedisService (来自 core/redis)

Redis服务接口用于会话数据存储、频率限制和违规记录管理。

SendChatMessageDto (本模块)

发送聊天消息的数据传输对象定义消息内容、范围和地图ID等字段。

ChatMessageResponseDto (本模块)

聊天消息响应的数据传输对象包含成功状态、消息ID和错误信息。

SystemStatusResponseDto (本模块)

系统状态响应的数据传输对象包含WebSocket状态、Zulip集成状态和系统信息。

核心特性

双向通信支持

  • WebSocket实时通信支持游戏客户端与服务器的实时双向通信
  • Zulip集成同步实现游戏内聊天与Zulip社群的双向消息同步
  • 事件驱动架构基于事件队列处理Zulip消息推送和游戏事件

会话状态管理

  • Redis持久化存储会话数据存储在Redis中支持服务重启后状态恢复
  • 自动过期清理:定时清理超时会话,释放系统资源
  • 多地图支持:支持玩家在不同地图间切换,自动更新地图玩家列表

消息过滤和安全

  • 敏感词过滤支持block和replace两种级别的敏感词处理
  • 频率限制控制:防止用户发送消息过于频繁导致刷屏
  • 位置权限验证防止用户向不匹配位置的Stream发送消息
  • 违规行为记录:记录和统计用户违规行为,支持监控和分析

业务规则引擎

  • 上下文注入机制根据玩家位置自动确定消息的目标Stream和Topic
  • 动态配置管理支持地图到Stream映射关系的动态配置和热重载
  • 权限分级控制:支持不同用户角色的权限控制和消息发送限制

潜在风险

会话数据丢失

  • Redis服务故障可能导致会话数据丢失影响用户体验
  • 建议配置Redis主从复制和持久化策略
  • 实现会话数据的定期备份和恢复机制

消息同步延迟

  • Zulip服务器网络延迟可能影响消息同步实时性
  • 大量并发消息可能导致事件队列处理延迟
  • 建议监控消息处理延迟并设置合理的超时机制

频率限制绕过

  • 恶意用户可能通过多个账号绕过频率限制
  • IP级别的频率限制可能影响正常用户
  • 建议结合用户行为分析和动态调整限制策略

敏感词过滤失效

  • 新型敏感词和变体可能绕过现有过滤规则
  • 过度严格的过滤可能影响正常交流
  • 建议定期更新敏感词库并优化过滤算法

WebSocket连接稳定性

  • 网络不稳定可能导致WebSocket连接频繁断开重连
  • 大量连接可能消耗过多服务器资源
  • 建议实现连接池管理和自动重连机制

位置验证绕过

  • 客户端修改可能绕过位置验证机制
  • 服务端位置验证逻辑需要持续完善
  • 建议结合多种验证手段和异常行为检测

使用示例

WebSocket 客户端连接

// 建立WebSocket连接
const socket = io('ws://localhost:3000/zulip');

// 监听连接事件
socket.on('connect', () => {
  console.log('Connected to Zulip WebSocket');
});

// 发送登录消息
socket.emit('login', {
  token: 'your-jwt-token'
});

// 发送聊天消息
socket.emit('chat', {
  content: '大家好!',
  scope: 'local',
  mapId: 'whale_port'
});

// 监听聊天消息
socket.on('chat_render', (data) => {
  console.log('收到消息:', data);
});

REST API 调用

// 发送聊天消息
const response = await fetch('/api/zulip/send-message', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your-jwt-token'
  },
  body: JSON.stringify({
    content: '测试消息',
    scope: 'global',
    mapId: 'whale_port'
  })
});

// 获取聊天历史
const history = await fetch('/api/zulip/chat-history?mapId=whale_port&limit=50');
const messages = await history.json();

// 获取系统状态
const status = await fetch('/api/zulip/system-status');
const systemInfo = await status.json();

服务集成示例

@Injectable()
export class GameChatService {
  constructor(
    private readonly zulipService: ZulipService,
    private readonly sessionManager: SessionManagerService
  ) {}

  async handlePlayerMessage(playerId: string, message: string) {
    // 获取玩家会话
    const session = await this.sessionManager.getSession(playerId);
    
    // 发送消息到Zulip
    const result = await this.zulipService.sendChatMessage({
      gameUserId: playerId,
      content: message,
      scope: 'local',
      mapId: session.mapId
    });
    
    return result;
  }
}

版本信息

  • 版本: 1.3.0
  • 作者: angjustinl
  • 创建时间: 2025-12-20
  • 最后修改: 2026-01-12

最近修改记录

  • 2026-01-12: 功能新增 - 添加完整的WebSocket事件接口文档包含所有事件的输入输出格式说明 (修改者: moyin)
  • 2026-01-07: 功能修改 - 更新业务逻辑和接口描述 (修改者: angjustinl)
  • 2025-12-20: 功能新增 - 创建Zulip游戏集成业务模块文档 (修改者: angjustinl)