# Zulip 集成系统 API 文档 ## WebSocket 连接 ### 连接地址 ``` ws://localhost:3000/game ``` ### 连接参数 连接时无需额外参数,认证通过 `login` 消息完成。 ## 消息类型 ### 1. 登录 (login) **请求:** ```json { "type": "login", "token": "user_game_token" } ``` **成功响应:** ```json { "t": "login_success", "sessionId": "session_abc123", "currentMap": "novice_village", "username": "player_name" } ``` **失败响应:** ```json { "t": "error", "code": "AUTH_FAILED", "message": "Token 验证失败" } ``` ### 2. 发送聊天消息 (chat) **请求:** ```json { "t": "chat", "content": "Hello, world!", "scope": "local" } ``` **参数说明:** | 参数 | 类型 | 必填 | 说明 | |-----|------|-----|------| | t | string | 是 | 固定值 "chat" | | content | string | 是 | 消息内容,最大 1000 字符 | | scope | string | 是 | 消息范围: "local" 或具体 topic 名称 | **成功响应:** ```json { "t": "chat_sent", "messageId": "msg_123", "timestamp": 1703500800000 } ``` **失败响应:** ```json { "t": "error", "code": "RATE_LIMIT", "message": "消息发送过于频繁,请稍后再试" } ``` ### 3. 接收聊天消息 (chat_render) **服务器推送:** ```json { "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) **请求:** ```json { "t": "position", "x": 150, "y": 200, "mapId": "novice_village" } ``` **参数说明:** | 参数 | 类型 | 必填 | 说明 | |-----|------|-----|------| | t | string | 是 | 固定值 "position" | | x | number | 是 | X 坐标 | | y | number | 是 | Y 坐标 | | mapId | string | 是 | 地图 ID | **响应:** ```json { "t": "position_updated", "stream": "Novice Village", "topic": "General" } ``` ### 5. 登出 (logout) **请求:** ```json { "type": "logout" } ``` **响应:** ```json { "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 ```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 检查系统健康状态。 **响应:** ```json { "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 ```