feat(zulip): 添加全面的 Zulip 集成系统
* **新增 Zulip 模块**:包含完整的集成服务,涵盖客户端池(client pool)、会话管理及事件处理。 * **新增 WebSocket 网关**:用于处理 Zulip 的实时事件监听与双向通信。 * **新增安全服务**:支持 API 密钥加密存储及凭据的安全管理。 * **新增配置管理服务**:支持配置热加载(hot-reload),实现动态配置更新。 * **新增错误处理与监控服务**:提升系统的可靠性与可观测性。 * **新增消息过滤服务**:用于内容校验及速率限制(流控)。 * **新增流初始化与会话清理服务**:优化资源管理与回收。 * **完善测试覆盖**:包含单元测试及端到端(e2e)集成测试。 * **完善详细文档**:包括 API 参考手册、配置指南及集成概述。 * **新增地图配置系统**:实现游戏地点与 Zulip Stream(频道)及 Topic(话题)的逻辑映射。 * **新增环境变量配置**:涵盖 Zulip 服务器地址、身份验证及监控相关设置。 * **更新 App 模块**:注册并启用新的 Zulip 集成模块。 * **更新 Redis 接口**:以支持增强型的会话管理功能。 * **实现 WebSocket 协议支持**:确保与 Zulip 之间的实时双向通信。
This commit is contained in:
377
docs/systems/zulip/README.md
Normal file
377
docs/systems/zulip/README.md
Normal file
@@ -0,0 +1,377 @@
|
||||
# Zulip 集成系统文档
|
||||
|
||||
## 概述
|
||||
|
||||
Zulip 集成系统是一个为 2D 社交 MMO 游戏设计的跨平台聊天解决方案。该系统实现了游戏内外的无缝互通,让不玩游戏的 Zulip 社群成员也能与游戏内玩家实时交流。
|
||||
|
||||
### 核心设计理念
|
||||
|
||||
系统采用 **统一网关 (Unified Gateway)** 架构,利用 Zulip 的 Stream-Topic 线程模型与游戏世界的空间概念进行映射:
|
||||
|
||||
| 游戏概念 | Zulip 概念 | 示例 |
|
||||
|---------|-----------|------|
|
||||
| Game World / Map | Stream | #Novice_Village |
|
||||
| Interactive Object / Event | Topic | Notice Board, Tavern Gossip |
|
||||
| Whisper / Party | Private Message | 私聊消息 |
|
||||
|
||||
### 架构优势
|
||||
|
||||
1. **客户端极度简化**: Godot 客户端无需处理 HTTP 请求、Long Polling 或复杂 JSON 解析
|
||||
2. **安全性**: Zulip API Key 永不下发到客户端,位置欺诈完全消除
|
||||
3. **协议统一**: 单一 WebSocket 协议,网络层代码减半
|
||||
|
||||
## 系统架构
|
||||
|
||||
```
|
||||
┌─────────────────┐ WebSocket ┌─────────────────────────────────────┐
|
||||
│ Godot Client │◄──────────────────►│ NestJS 中间件服务器 │
|
||||
│ (Game Client) │ Game Protocol │ ┌─────────────────────────────────┐│
|
||||
└─────────────────┘ │ │ WebSocket Gateway ││
|
||||
│ │ ├─ Session Manager ││
|
||||
│ │ ├─ Message Filter ││
|
||||
│ │ └─ Zulip Client Pool ││
|
||||
│ └─────────────────────────────────┘│
|
||||
└──────────────┬──────────────────────┘
|
||||
│ REST API / Long Polling
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ Zulip Server │
|
||||
│ ├─ REST API │
|
||||
│ └─ Event Queue │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 1. WebSocket Gateway (`zulip-websocket.gateway.ts`)
|
||||
|
||||
统一网关,处理所有 Godot 客户端连接,实现游戏协议到 Zulip 协议的转换。
|
||||
|
||||
**主要功能:**
|
||||
- 连接认证和会话管理
|
||||
- 消息路由和协议转换
|
||||
- 权限控制和上下文注入
|
||||
|
||||
**支持的消息类型:**
|
||||
- `login`: 玩家登录
|
||||
- `chat`: 发送聊天消息
|
||||
- `position_update`: 位置更新
|
||||
- `logout`: 玩家登出
|
||||
|
||||
### 2. Session Manager (`session-manager.service.ts`)
|
||||
|
||||
会话管理器,维护 Socket_ID 与 Zulip_Queue_ID 的绑定关系。
|
||||
|
||||
**主要功能:**
|
||||
- 会话创建/销毁
|
||||
- 玩家位置跟踪
|
||||
- 上下文注入(根据位置确定 Stream/Topic)
|
||||
- 空间过滤(获取指定地图的所有 Socket)
|
||||
|
||||
### 3. Zulip Client Pool (`zulip-client-pool.service.ts`)
|
||||
|
||||
Zulip 客户端池,为每个用户维护专用的 Zulip 客户端实例。
|
||||
|
||||
**主要功能:**
|
||||
- API Key 管理
|
||||
- 事件队列注册
|
||||
- 消息发送/接收
|
||||
- 客户端生命周期管理
|
||||
|
||||
### 4. Message Filter (`message-filter.service.ts`)
|
||||
|
||||
消息过滤器,实施内容审核和频率控制。
|
||||
|
||||
**主要功能:**
|
||||
- 敏感词过滤
|
||||
- 频率限制(默认 10 条/分钟)
|
||||
- 消息长度限制(默认 1000 字符)
|
||||
- 重复内容检测
|
||||
- 权限验证
|
||||
|
||||
### 5. Config Manager (`config-manager.service.ts`)
|
||||
|
||||
配置管理器,管理地图映射配置和系统参数。
|
||||
|
||||
**主要功能:**
|
||||
- 地图到 Stream 的映射
|
||||
- 交互对象到 Topic 的映射
|
||||
- 配置热重载
|
||||
- 配置验证
|
||||
|
||||
### 6. Stream Initializer Service (`stream-initializer.service.ts`)
|
||||
|
||||
Stream 初始化服务,在系统启动时自动检查并创建缺失的 Zulip Streams。
|
||||
|
||||
**主要功能:**
|
||||
- 启动时自动检查所有地图对应的 Streams
|
||||
- 自动创建缺失的 Streams
|
||||
- 使用 Bot API Key 或管理员账号创建 Streams
|
||||
- 记录初始化结果和错误
|
||||
|
||||
**权限说明:**
|
||||
- Bot 账号可能缺少创建 Stream 的权限
|
||||
- 建议使用管理员账号手动创建 Streams
|
||||
- 或在 Zulip 服务器中为 Bot 授予相应权限
|
||||
|
||||
### 7. Monitoring Service (`monitoring.service.ts`)
|
||||
|
||||
监控服务,提供系统健康检查和指标收集。
|
||||
|
||||
**主要功能:**
|
||||
- 连接指标监控
|
||||
- 消息指标监控
|
||||
- 系统健康检查
|
||||
- 告警通知
|
||||
|
||||
## 消息协议
|
||||
|
||||
### 客户端发送格式
|
||||
|
||||
#### 登录消息
|
||||
```json
|
||||
{
|
||||
"type": "login",
|
||||
"token": "user_game_token"
|
||||
}
|
||||
```
|
||||
|
||||
#### 聊天消息
|
||||
```json
|
||||
{
|
||||
"t": "chat",
|
||||
"content": "Hello",
|
||||
"scope": "local"
|
||||
}
|
||||
```
|
||||
|
||||
#### 位置更新
|
||||
```json
|
||||
{
|
||||
"t": "position",
|
||||
"x": 100,
|
||||
"y": 200,
|
||||
"mapId": "novice_village"
|
||||
}
|
||||
```
|
||||
|
||||
### 客户端接收格式
|
||||
|
||||
#### 聊天渲染消息
|
||||
```json
|
||||
{
|
||||
"t": "chat_render",
|
||||
"from": "User_B",
|
||||
"txt": "Hi",
|
||||
"bubble": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 登录确认
|
||||
```json
|
||||
{
|
||||
"t": "login_success",
|
||||
"sessionId": "session_123",
|
||||
"currentMap": "novice_village"
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误消息
|
||||
```json
|
||||
{
|
||||
"t": "error",
|
||||
"code": "RATE_LIMIT",
|
||||
"message": "消息发送过于频繁,请稍后再试"
|
||||
}
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 环境变量配置
|
||||
|
||||
```bash
|
||||
# Zulip 服务器配置
|
||||
ZULIP_SERVER_URL=https://your-zulip-server.com
|
||||
ZULIP_BOT_EMAIL=bot@your-zulip-server.com
|
||||
ZULIP_BOT_API_KEY=your-bot-api-key
|
||||
|
||||
# WebSocket 配置
|
||||
WEBSOCKET_PORT=3001
|
||||
WEBSOCKET_NAMESPACE=/game
|
||||
|
||||
# 消息配置
|
||||
MESSAGE_RATE_LIMIT=10 # 消息频率限制(条/分钟)
|
||||
MESSAGE_MAX_LENGTH=1000 # 消息最大长度
|
||||
|
||||
# 会话配置
|
||||
SESSION_TIMEOUT=30 # 会话超时时间(分钟)
|
||||
CLEANUP_INTERVAL=5 # 清理间隔(分钟)
|
||||
```
|
||||
|
||||
### Stream 初始化
|
||||
|
||||
系统在启动时会自动检查并尝试创建缺失的 Zulip Streams。
|
||||
|
||||
**注意事项:**
|
||||
|
||||
- Bot 账号可能缺少创建 Stream 的权限
|
||||
- 建议使用管理员账号预先创建所有 Streams
|
||||
- 或在 Zulip 服务器中为 Bot 授予 "Create streams" 权限
|
||||
|
||||
**手动创建 Streams:**
|
||||
|
||||
```bash
|
||||
# 使用测试脚本创建所有地图区域的 Streams
|
||||
node test-stream-initialization.js
|
||||
```
|
||||
|
||||
详细配置说明请参考 [配置管理指南](./configuration.md)。
|
||||
|
||||
### 地图映射配置
|
||||
|
||||
配置文件位置: `config/zulip/map-config.json`
|
||||
|
||||
系统支持 9 个地图区域,每个区域对应一个 Zulip Stream:
|
||||
|
||||
1. **鲸之港 (Whale Port)** - 中心城区,默认出生点
|
||||
2. **南瓜谷 (Pumpkin Valley)** - 新手学习区
|
||||
3. **Offer 城 (Offer City)** - 职业发展区
|
||||
4. **模型工厂 (Model Factory)** - AI/代码构建区
|
||||
5. **内核岛 (Kernel Island)** - 核心技术研究区
|
||||
6. **摸鱼海滩 (Moyu Beach)** - 休闲娱乐区
|
||||
7. **天梯峰 (Ladder Peak)** - 挑战竞赛区
|
||||
8. **星河湾 (Galaxy Bay)** - 创意设计区
|
||||
9. **数据遗迹 (Data Ruins)** - 数据库归档区
|
||||
|
||||
配置示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"description": "基于像素大地图的 Zulip 映射配置",
|
||||
"maps": [
|
||||
{
|
||||
"mapId": "whale_port",
|
||||
"mapName": "鲸之港",
|
||||
"zulipStream": "Whale Port",
|
||||
"description": "中心城区,交通枢纽与主要聚会点",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "whale_statue",
|
||||
"objectName": "鲸鱼雕像",
|
||||
"zulipTopic": "Announcements",
|
||||
"position": { "x": 600, "y": 400 }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 数据流程
|
||||
|
||||
### 发送消息流程 (游戏 → Zulip)
|
||||
|
||||
1. 玩家在游戏中输入消息
|
||||
2. Godot 客户端通过 WebSocket 发送 `chat` 消息
|
||||
3. WebSocket Gateway 接收消息
|
||||
4. Session Manager 获取玩家当前位置
|
||||
5. 上下文注入:根据位置确定目标 Stream/Topic
|
||||
6. Message Filter 进行内容过滤和频率检查
|
||||
7. Zulip Client Pool 使用用户的 API Key 发送消息到 Zulip
|
||||
8. 返回发送确认给客户端
|
||||
|
||||
### 接收消息流程 (Zulip → 游戏)
|
||||
|
||||
1. Zulip 服务器推送消息事件到 Event Queue
|
||||
2. Zulip Event Processor 接收并处理事件
|
||||
3. Session Manager 进行空间过滤,确定目标玩家
|
||||
4. 消息转换为游戏协议格式
|
||||
5. WebSocket Gateway 推送 `chat_render` 消息给目标客户端
|
||||
6. Godot 客户端显示聊天气泡
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 错误码说明
|
||||
|
||||
| 错误码 | 说明 | 处理建议 |
|
||||
|-------|------|---------|
|
||||
| `AUTH_FAILED` | 认证失败 | 检查 Token 有效性 |
|
||||
| `RATE_LIMIT` | 频率限制 | 等待后重试 |
|
||||
| `CONTENT_FILTERED` | 内容被过滤 | 修改消息内容 |
|
||||
| `PERMISSION_DENIED` | 权限不足 | 检查用户权限 |
|
||||
| `ZULIP_ERROR` | Zulip 服务错误 | 系统自动重试 |
|
||||
| `SESSION_EXPIRED` | 会话过期 | 重新登录 |
|
||||
|
||||
### 降级策略
|
||||
|
||||
当 Zulip 服务不可用时,系统会自动切换到本地聊天模式:
|
||||
- 消息仅在游戏内传播
|
||||
- 不同步到 Zulip
|
||||
- 服务恢复后自动切换回正常模式
|
||||
|
||||
## 安全机制
|
||||
|
||||
### API Key 安全
|
||||
|
||||
- API Key 加密存储在数据库中
|
||||
- 永不下发到客户端
|
||||
- 支持强制刷新机制
|
||||
|
||||
### 消息安全
|
||||
|
||||
- 敏感词过滤
|
||||
- 频率限制防刷屏
|
||||
- 位置验证防欺诈
|
||||
- 消息长度限制
|
||||
|
||||
### 连接安全
|
||||
|
||||
- Token 验证
|
||||
- 会话超时自动断开
|
||||
- 异常连接检测和拒绝
|
||||
|
||||
## 监控指标
|
||||
|
||||
### 连接指标
|
||||
- `zulip.connections.active`: 活跃连接数
|
||||
- `zulip.connections.total`: 总连接数
|
||||
- `zulip.connections.errors`: 连接错误数
|
||||
|
||||
### 消息指标
|
||||
- `zulip.messages.sent`: 发送消息数
|
||||
- `zulip.messages.received`: 接收消息数
|
||||
- `zulip.messages.filtered`: 被过滤消息数
|
||||
- `zulip.messages.latency`: 消息延迟
|
||||
|
||||
### 系统指标
|
||||
- `zulip.sessions.active`: 活跃会话数
|
||||
- `zulip.zulip_clients.active`: 活跃 Zulip 客户端数
|
||||
- `zulip.event_queues.active`: 活跃事件队列数
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [zulip-js 库使用指南](./zulip-js.md)
|
||||
- [API 接口文档](./api.md)
|
||||
- [WebSocket 协议详解](./websocket-protocol.md)
|
||||
- [配置管理指南](./configuration.md)
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v2.0.0 (2025-12-25)
|
||||
- 更新地图配置为 9 区域系统
|
||||
- 添加 Stream Initializer Service 自动初始化服务
|
||||
- 更新默认出生点为鲸之港 (Whale Port)
|
||||
- 添加地图区域描述字段
|
||||
- 修复上下文注入使用 ConfigManager
|
||||
- 改进错误处理和日志记录
|
||||
|
||||
### v1.0.0 (2025-12-25)
|
||||
- 初始版本发布
|
||||
- 实现 WebSocket Gateway 统一网关
|
||||
- 实现 Session Manager 会话管理
|
||||
- 实现 Zulip Client Pool 客户端池
|
||||
- 实现 Message Filter 消息过滤
|
||||
- 实现 Config Manager 配置管理
|
||||
- 实现 Monitoring Service 监控服务
|
||||
- 完成集成测试覆盖
|
||||
Reference in New Issue
Block a user