# 实时网关协议草案 本文档描述 `realtime-gateway` 第一版协议草案,范围只覆盖 MVP。 --- ## 1. 连接方式 - 协议:WebSocket - 地址:`/ws` - 编码:JSON - 通信模式:客户端主动发消息,服务端返回状态或事件 --- ## 2. 消息类型 客户端上行 `type`: - `authenticate` - `join_channel` - `subscribe` - `publish` - `snapshot` 服务端下行 `type`: - `welcome` - `authenticated` - `subscribed` - `published` - `snapshot` - `event` - `error` --- ## 3. 鉴权 ### 3.1 authenticate ```json { "type": "authenticate", "role": "producer", "token": "dev-producer-token" } ``` 说明: - `role` 可选值:`producer`、`consumer`、`controller` - 第一版 `consumer` 可允许匿名,是否启用由配置控制 ### 3.2 join_channel ```json { "type": "join_channel", "role": "producer", "channelId": "ch-xxxx", "token": "producer-token" } ``` 说明: - `channelId` 必填 - `token` 必须和 `channelId` 对应 - `role` 不同,使用的 token 也不同 - `producerToken` - `consumerToken` - `controllerToken` --- ## 4. 订阅 ### 4.1 subscribe ```json { "type": "subscribe", "subscriptions": [ { "deviceId": "child-001", "topic": "telemetry.location" } ] } ``` 支持字段: - `channelId` - `deviceId` - `groupId` - `topic` 第一版匹配规则: - 非空字段必须全部匹配 - 空字段视为不过滤 --- ## 5. 发布 ### 5.1 publish ```json { "type": "publish", "envelope": { "schemaVersion": 1, "messageId": "msg-001", "timestamp": 1711267200000, "topic": "telemetry.location", "source": { "kind": "producer", "id": "watch-001", "mode": "real" }, "target": { "channelId": "ch-xxxx", "deviceId": "child-001", "groupId": "class-a" }, "payload": { "lat": 31.2304, "lng": 121.4737, "speed": 1.2, "bearing": 90, "accuracy": 6, "coordSystem": "GCJ02" } } } ``` 说明: - 只有 `producer` 和 `controller` 能发布 - 第一版不做复杂 schema 校验 - 第一版缓存键为 `channelId + deviceId` - 如果连接已经通过 `join_channel` 加入通道,服务端会自动补全 `target.channelId` --- ## 6. 快照 ### 6.1 snapshot ```json { "type": "snapshot", "subscriptions": [ { "channelId": "ch-xxxx", "deviceId": "child-001" } ] } ``` 服务端返回: ```json { "type": "snapshot", "sessionId": "sess-2", "state": { "schemaVersion": 1, "timestamp": 1711267200000, "topic": "telemetry.location", "source": { "kind": "producer", "id": "watch-001", "mode": "real" }, "target": { "deviceId": "child-001" }, "payload": { "lat": 31.2304, "lng": 121.4737 } } } ``` --- ## 7. 服务端消息 ### 7.1 welcome ```json { "type": "welcome", "sessionId": "sess-1" } ``` ### 7.2 authenticated ```json { "type": "authenticated", "sessionId": "sess-1" } ``` ### 7.3 subscribed ```json { "type": "subscribed", "sessionId": "sess-1" } ``` ### 7.4 joined_channel ```json { "type": "joined_channel", "sessionId": "sess-1", "state": { "channelId": "ch-xxxx", "deliveryMode": "cache_latest" } } ``` ### 7.5 published ```json { "type": "published", "sessionId": "sess-1" } ``` ### 7.6 event ```json { "type": "event", "envelope": { "schemaVersion": 1, "timestamp": 1711267200000, "topic": "telemetry.location", "source": { "kind": "producer", "id": "watch-001", "mode": "real" }, "target": { "channelId": "ch-xxxx", "deviceId": "child-001" }, "payload": { "lat": 31.2304, "lng": 121.4737 } } } ``` ### 7.7 error ```json { "type": "error", "error": "authentication failed" } ``` --- ## 8. 第一版约束 - 不做历史回放协议 - 不做压缩和二进制编码 - 不做批量发布 - 不做通配符 topic - 不做持久会话 - 不做 ACK 队列 --- ## 9. 管理接口 ### 9.1 创建 channel `POST /api/channel/create` 请求: ```json { "label": "debug-a", "deliveryMode": "cache_latest", "ttlSeconds": 28800 } ``` 返回: ```json { "snapshot": { "id": "ch-xxxx", "label": "debug-a", "deliveryMode": "cache_latest" }, "producerToken": "....", "consumerToken": "....", "controllerToken": "...." } ``` ### 9.2 管理台读取接口 - `GET /api/admin/overview` - `GET /api/admin/sessions` - `GET /api/admin/latest` - `GET /api/admin/channels` - `GET /api/admin/traffic` - `GET /api/admin/live` --- ## 10. 第二阶段预留 后续协议可以增加: - `command` - `batch_publish` - `rule_event` - `plugin_status` - `replay_control` - `auth_refresh`