Files
whale-town-end/docs/systems/zulip/api.md
angjustinl 55cfda0532 feat(zulip): 添加全面的 Zulip 集成系统
* **新增 Zulip 模块**:包含完整的集成服务,涵盖客户端池(client pool)、会话管理及事件处理。
* **新增 WebSocket 网关**:用于处理 Zulip 的实时事件监听与双向通信。
* **新增安全服务**:支持 API 密钥加密存储及凭据的安全管理。
* **新增配置管理服务**:支持配置热加载(hot-reload),实现动态配置更新。
* **新增错误处理与监控服务**:提升系统的可靠性与可观测性。
* **新增消息过滤服务**:用于内容校验及速率限制(流控)。
* **新增流初始化与会话清理服务**:优化资源管理与回收。
* **完善测试覆盖**:包含单元测试及端到端(e2e)集成测试。
* **完善详细文档**:包括 API 参考手册、配置指南及集成概述。
* **新增地图配置系统**:实现游戏地点与 Zulip Stream(频道)及 Topic(话题)的逻辑映射。
* **新增环境变量配置**:涵盖 Zulip 服务器地址、身份验证及监控相关设置。
* **更新 App 模块**:注册并启用新的 Zulip 集成模块。
* **更新 Redis 接口**:以支持增强型的会话管理功能。
* **实现 WebSocket 协议支持**:确保与 Zulip 之间的实时双向通信。
2025-12-25 22:22:30 +08:00

5.4 KiB
Raw Blame History

Zulip 集成系统 API 文档

WebSocket 连接

连接地址

ws://localhost:3000/game

连接参数

连接时无需额外参数,认证通过 login 消息完成。

消息类型

1. 登录 (login)

请求:

{
  "type": "login",
  "token": "user_game_token"
}

成功响应:

{
  "t": "login_success",
  "sessionId": "session_abc123",
  "currentMap": "novice_village",
  "username": "player_name"
}

失败响应:

{
  "t": "error",
  "code": "AUTH_FAILED",
  "message": "Token 验证失败"
}

2. 发送聊天消息 (chat)

请求:

{
  "t": "chat",
  "content": "Hello, world!",
  "scope": "local"
}

参数说明:

参数 类型 必填 说明
t string 固定值 "chat"
content string 消息内容,最大 1000 字符
scope string 消息范围: "local" 或具体 topic 名称

成功响应:

{
  "t": "chat_sent",
  "messageId": "msg_123",
  "timestamp": 1703500800000
}

失败响应:

{
  "t": "error",
  "code": "RATE_LIMIT",
  "message": "消息发送过于频繁,请稍后再试"
}

3. 接收聊天消息 (chat_render)

服务器推送:

{
  "t": "chat_render",
  "from": "other_player",
  "txt": "Hi there!",
  "bubble": true,
  "timestamp": 1703500800000
}

参数说明:

参数 类型 说明
t string 固定值 "chat_render"
from string 发送者名称
txt string 消息内容
bubble boolean 是否显示气泡
timestamp number 消息时间戳

4. 位置更新 (position_update)

请求:

{
  "t": "position",
  "x": 150,
  "y": 200,
  "mapId": "novice_village"
}

参数说明:

参数 类型 必填 说明
t string 固定值 "position"
x number X 坐标
y number Y 坐标
mapId string 地图 ID

响应:

{
  "t": "position_updated",
  "stream": "Novice Village",
  "topic": "General"
}

5. 登出 (logout)

请求:

{
  "type": "logout"
}

响应:

{
  "t": "logout_success"
}

错误码

错误码 HTTP 等效 说明 处理建议
AUTH_FAILED 401 认证失败Token 无效或过期 重新获取 Token 并登录
RATE_LIMIT 429 消息发送频率超限 等待 60 秒后重试
CONTENT_FILTERED 400 消息内容被过滤 修改消息内容后重试
CONTENT_TOO_LONG 400 消息内容超长 缩短消息长度
PERMISSION_DENIED 403 权限不足 检查用户权配置
SESSION_EXPIRED 401 会话已过期 重新登录
SESSION_NOT_FOUND 404 会话不存在 重新登录
ZULIP_ERROR 502 Zulip 服务错误 系统自动重试,无需处理
INTERNAL_ERROR 500 内部服务器错误 联系管理员

频率限制

消息发送限制

  • 默认限制: 10 条/分钟
  • 超限后返回 RATE_LIMIT 错误
  • 限制窗口: 滑动窗口60 秒

连接限制

  • 单用户最大连接数: 3
  • 超限后新连接被拒绝

消息过滤规则

内容过滤

  1. 敏感词过滤: 包含敏感词的消息将被拒绝
  2. 长度限制: 消息最大 1000 字符
  3. 重复检测: 连续发送相同内容将被拒绝

权限验证

  1. 位置验证: 只能向当前所在地图对应的 Stream 发送消息
  2. Stream 权限: 只能访问配置中允许的 Stream

示例代码

JavaScript/TypeScript

// 连接 WebSocket
const socket = new WebSocket('ws://localhost:3000/game');

// 连接成功
socket.onopen = () => {
  // 发送登录消息
  socket.send(JSON.stringify({
    type: 'login',
    token: 'your_game_token'
  }));
};

// 接收消息
socket.onmessage = (event) => {
  const data = JSON.parse(event.data);
  
  switch (data.t) {
    case 'login_success':
      console.log('登录成功:', data.sessionId);
      break;
    case 'chat_render':
      console.log(`${data.from}: ${data.txt}`);
      break;
    case 'error':
      console.error(`错误 [${data.code}]: ${data.message}`);
      break;
  }
};

// 发送聊天消息
function sendChat(content: string) {
  socket.send(JSON.stringify({
    t: 'chat',
    content: content,
    scope: 'local'
  }));
}

// 更新位置
function updatePosition(x: number, y: number, mapId: string) {
  socket.send(JSON.stringify({
    t: 'position',
    x: x,
    y: y,
    mapId: mapId
  }));
}

健康检查接口

GET /health

检查系统健康状态。

响应:

{
  "status": "healthy",
  "components": {
    "websocket": "healthy",
    "zulip": "healthy",
    "redis": "healthy"
  },
  "metrics": {
    "activeConnections": 42,
    "activeSessions": 40,
    "messagesSentLastMinute": 156
  }
}

GET /metrics

获取系统指标Prometheus 格式)。

响应:

# HELP zulip_connections_active Active WebSocket connections
# TYPE zulip_connections_active gauge
zulip_connections_active 42

# HELP zulip_messages_sent_total Total messages sent
# TYPE zulip_messages_sent_total counter
zulip_messages_sent_total 15678

# HELP zulip_message_latency_seconds Message processing latency
# TYPE zulip_message_latency_seconds histogram
zulip_message_latency_seconds_bucket{le="0.1"} 14500
zulip_message_latency_seconds_bucket{le="0.5"} 15600
zulip_message_latency_seconds_bucket{le="1"} 15678