# 实时网关协议草案
> 文档版本：v1.0
> 最后更新：2026-04-02 08:28:05


本文档描述 `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`



