# 服务端接口与 WebSocket 消息类型

## 一、HTTP REST API 接口

### 1.1 配置接口

**GET /config**
- **功能**: 获取服务器配置信息
- **参数**: 无
- **响应**:
  ```json
  {
    "useWebSocket": boolean,
    "startupMode": string,
    "logging": string
  }
  ```

### 1.2 头像上传接口

**POST /api/upload/avatar**
- **功能**: 上传用户头像
- **参数**:
  - `userId` (body): 用户ID
  - `avatar` (file): 头像文件
- **响应**:
  ```json
  {
    "success": boolean,
    "avatarUrl": string,
    "message": string
  }
  ```

### 1.3 会话管理接口

**GET /signaling/connection-ids**
- **功能**: 获取所有活跃的连接ID（无需会话认证）
- **响应**:
  ```json
  {
    "connectionIds": string[],
    "totalCount": number
  }
  ```

**PUT /signaling**
- **功能**: 创建新的会话，获取会话ID
- **参数**: 无
- **响应**:
  ```json
  {
    "sessionId": string
  }
  ```

**GET /signaling**
- **功能**: 获取当前会话的所有信令消息
- **认证**: 需要在请求头 `Session-Id` 中提供会话ID
- **参数**:
  - `fromtime` (query): 起始时间戳，用于增量拉取
- **响应**:
  ```json
  {
    "messages": [
      {
        "connectionId": string,
        "type": "connect|disconnect|offer|answer|candidate",
        "datetime": number,
        "sdp": string,
        "polite": boolean,
        "candidate": string,
        "sdpMLineIndex": number,
        "sdpMid": string
      }
    ],
    "datetime": number
  }
  ```

**DELETE /signaling**
- **功能**: 删除当前会话及其所有连接
- **认证**: 需要会话ID
- **响应**: 200 OK

### 1.4 连接管理接口

**GET /signaling/connection**
- **功能**: 获取当前会话的连接列表
- **认证**: 需要会话ID
- **响应**:
  ```json
  {
    "connections": [
      {
        "connectionId": string,
        "type": "connect",
        "datetime": number
      }
    ]
  }
  ```

**PUT /signaling/connection**
- **功能**: 创建新的连接
- **认证**: 需要会话ID
- **请求体**:
  ```json
  {
    "connectionId": string
  }
  ```
- **响应**:
  ```json
  {
    "connectionId": string,
    "polite": boolean,
    "type": "connect",
    "datetime": number
  }
  ```

**DELETE /signaling/connection**
- **功能**: 删除指定的连接
- **认证**: 需要会话ID
- **请求体**:
  ```json
  {
    "connectionId": string
  }
  ```
- **响应**:
  ```json
  {
    "connectionId": string
  }
  ```

### 1.5 WebRTC 信令交换接口

**GET /signaling/offer**
- **功能**: 获取 offer 信令消息列表
- **认证**: 需要会话ID
- **参数**: `fromtime` (query): 起始时间戳
- **响应**:
  ```json
  {
    "offers": [
      {
        "connectionId": string,
        "sdp": string,
        "polite": boolean,
        "type": "offer",
        "datetime": number
      }
    ]
  }
  ```

**POST /signaling/offer**
- **功能**: 发送 offer 信令
- **认证**: 需要会话ID
- **请求体**:
  ```json
  {
    "connectionId": string,
    "sdp": string
  }
  ```
- **响应**: 200 OK

**GET /signaling/answer**
- **功能**: 获取 answer 信令消息列表
- **认证**: 需要会话ID
- **参数**: `fromtime` (query): 起始时间戳
- **响应**:
  ```json
  {
    "answers": [
      {
        "connectionId": string,
        "sdp": string,
        "type": "answer",
        "datetime": number
      }
    ]
  }
  ```

**POST /signaling/answer**
- **功能**: 发送 answer 信令
- **认证**: 需要会话ID
- **请求体**:
  ```json
  {
    "connectionId": string,
    "sdp": string
  }
  ```
- **响应**: 200 OK

**GET /signaling/candidate**
- **功能**: 获取 ICE candidate 信令消息列表
- **认证**: 需要会话ID
- **参数**: `fromtime` (query): 起始时间戳
- **响应**:
  ```json
  {
    "candidates": [
      {
        "connectionId": string,
        "candidate": string,
        "sdpMLineIndex": number,
        "sdpMid": string,
        "type": "candidate",
        "datetime": number
      }
    ]
  }
  ```

**POST /signaling/candidate**
- **功能**: 发送 ICE candidate 信令
- **认证**: 需要会话ID
- **请求体**:
  ```json
  {
    "connectionId": string,
    "candidate": string,
    "sdpMLineIndex": number,
    "sdpMid": string
  }
  ```
- **响应**: 200 OK

### 1.6 房间信息接口

**GET /signaling/rooms**
- **功能**: 获取房间和用户信息
- **认证**: 需要会话ID
- **响应**:
  ```json
  {
    "rooms": [
      {
        "roomId": string,
        "users": [
          {
            "sessionId": string,
            "connected": boolean
          }
        ],
        "userCount": number
      }
    ],
    "totalRooms": number
  }
  ```

---

## 二、WebSocket 消息类型

### 2.1 连接生命周期消息

#### connect（连接建立）

- **方向**: 客户端 → 服务端 → 客户端
- **客户端发送**:
  ```json
  {
    "type": "connect",
    "connectionId": string
  }
  ```
- **服务端响应**:
  ```json
  {
    "type": "connect",
    "connectionId": string,
    "polite": boolean,
    "role": "host|participant",
    "participantId": string
  }
  ```
- **说明**: 建立连接并协商 polite 标志以处理连接冲突。`polite=true` 表示后加入方（participant），`polite=false` 表示先加入方（host）。

#### disconnect（连接断开）

- **方向**: 客户端 → 服务端 → 客户端
- **客户端发送**:
  ```json
  {
    "type": "disconnect",
    "connectionId": string
  }
  ```
- **服务端响应**:
  ```json
  {
    "type": "disconnect",
    "connectionId": string,
    "reason": "normal|host-left"
  }
  ```
- **说明**: 断开连接。当 host 离开时，reason 为 `host-left`。

#### participant-joined（参与者加入，仅私有模式）

- **方向**: 服务端 → host 客户端
- **格式**:
  ```json
  {
    "type": "participant-joined",
    "connectionId": string,
    "participantId": string
  }
  ```
- **说明**: 通知 host 有新的 participant 加入。

#### participant-left（参与者离开，仅私有模式）

- **方向**: 服务端 → host 客户端 / 其他 participants
- **格式**:
  ```json
  {
    "type": "participant-left",
    "connectionId": string,
    "participantId": string
  }
  ```
- **说明**: 通知有 participant 离开房间。

### 2.2 WebRTC SDP 交换消息

#### offer

- **方向**: 双向
- **格式**:
  ```json
  {
    "type": "offer",
    "from": string,
    "to": string,
    "data": {
      "sdp": string,
      "connectionId": string,
      "participantId": string
    },
    "participantId": string
  }
  ```
- **路由规则**:
  - **私有模式**: Host → 所有/特定 Participant；Participant → Host
  - **公共模式**: Peer → 所有其他 Peers

#### answer

- **方向**: 双向
- **格式**:
  ```json
  {
    "type": "answer",
    "from": string,
    "to": string,
    "data": {
      "sdp": string,
      "connectionId": string,
      "participantId": string
    },
    "participantId": string
  }
  ```
- **路由规则**:
  - **私有模式**: Participant → Host；Host → 特定 Participant
  - **公共模式**: Peer → 特定 Peer

#### candidate

- **方向**: 双向
- **格式**:
  ```json
  {
    "type": "candidate",
    "from": string,
    "to": string,
    "data": {
      "candidate": string,
      "sdpMLineIndex": number,
      "sdpMid": string,
      "connectionId": string,
      "participantId": string
    },
    "participantId": string
  }
  ```
- **路由规则**: 与 answer 消息相同。

### 2.3 心跳/控制消息

#### ping（服务端 → 客户端）

- **格式**:
  ```json
  {
    "from": string,
    "to": string,
    "type": "on-message",
    "data": {
      "type": "ping"
    }
  }
  ```
- **说明**: 服务端心跳检测（可选功能，默认未启用）。

#### pong（客户端 → 服务端）

- **格式**:
  ```json
  {
    "type": "pong"
  }
  ```
- **说明**: 心跳应答。

### 2.4 自定义消息

#### on-message（通用消息传递）

- **方向**: 双向
- **格式**:
  ```json
  {
    "type": "on-message",
    "from": string,
    "to": string,
    "data": {
      "message": string|object,
      "connectionId": string,
      "senderId": string,
      "participantId": string
    }
  }
  ```
- **路由规则**:
  - **私有模式**: Host ↔ 所有 Participants；Participant ↔ Host
  - **公共模式**: Peer → Peer
- **说明**: 传输文本、数据或聊天消息。

#### broadcast（广播消息）

- **客户端发送**:
  ```json
  {
    "type": "broadcast",
    "message": string|object,
    "targetConnectionId": string
  }
  ```
- **服务端转发**:
  ```json
  {
    "type": "broadcast",
    "message": string|object,
    "from": "server"
  }
  ```
- **说明**: 若指定 `targetConnectionId`，则广播给该连接组内的所有成员；否则广播给所有连接的客户端。

### 2.5 呼叫请求消息

#### call-request

- **方向**: 客户端 → 服务端 → 客户端
- **格式**:
  ```json
  {
    "type": "call-request",
    "data": string
  }
  ```
- **路由规则**:
  - **私有模式**: Participant → Server → Host
  - **公共模式**: Peer → Server → 所有其他 Peers
- **说明**: 发起呼叫请求。

---

## 三、通信模式说明

### 3.1 公共模式（Public Mode）

- 所有连接的客户端都可以相互通信
- offer/answer/candidate 向所有其他客户端广播

### 3.2 私有模式（Private Mode）

- 一个 connectionId 对应一个房间，包含 1 个 host 和多个 participants
- Host 是第一个加入 connectionId 的客户端（`polite=false`）
- Participants 是后续加入的客户端（`polite=true`）
- Host 发送的消息可单播给特定 participant 或广播给所有 participants
- Participant 发送的消息仅发送给 host
- 当 host 离开时，整个房间关闭，所有 participants 被断开连接
- 当 participant 离开时，房间继续存在

---

## 四、会话与连接管理

### 4.1 会话（Session）

- 每个客户端通过 `PUT /signaling` 创建一个唯一的会话
- 会话ID通过 `Session-Id` 请求头在所有后续 HTTP 请求中传递
- 会话管理超时：10 秒无请求则自动删除会话
- 一个会话可以包含多个连接ID

### 4.2 连接（Connection）

- 连接ID由客户端生成和指定
- 在 HTTP 模式下，连接对通过 connectionId 自动配对
- 在 WebSocket 私有模式下，第一个连接是 host，后续连接是 participants
- 一个连接对在私有模式下支持 1 对多（1 host + N participants）

### 4.3 Polite 标志

- 用于处理 WebRTC 连接冲突（双方同时发送 offer 的情况）
- `polite=true`：该端应放弃 offer，接收来自另一端的 offer
- `polite=false`：该端具有优先权，可以发送 offer
- 私有模式下：host → `polite=false`，participants → `polite=true`

---

## 五、关键设计特性

1. **双协议支持**: 同时支持 HTTP 轮询和 WebSocket 两种信令协议
2. **两种通信模式**: 公共模式（全连通）和私有模式（1 对多房间）
3. **Polite 机制**: 自动处理并发 offer 冲突
4. **会话隔离**: 通过 Session-ID 在 HTTP 模式下隔离不同客户端的消息
5. **心跳检测**: 可选的心跳机制防止连接超时
6. **消息增量拉取**: HTTP GET 支持 fromtime 参数实现增量消息获取
7. **头像上传**: 内置文件上传功能支持用户头像管理
8. **API 文档**: 集成 Swagger 提供自动生成的 API 文档

---

## 六、源文件路径

| 文件 | 功能 |
|------|------|
| `src/index.ts` | 应用入口，配置和启动服务器 |
| `src/server.ts` | Express 服务器创建，中间件配置 |
| `src/signaling.ts` | HTTP REST 路由定义 |
| `src/websocket.ts` | WebSocket 服务器和消息路由 |
| `src/class/httphandler.ts` | HTTP 处理器，核心业务逻辑 |
| `src/class/websockethandler.ts` | WebSocket 处理器，消息分发逻辑 |
| `src/class/offer.ts` | Offer 类定义 |
| `src/class/answer.ts` | Answer 类定义 |
| `src/class/candidate.ts` | Candidate 类定义 |
| `src/class/options.ts` | 配置选项接口 |
| `src/swagger.ts` | Swagger API 文档配置 |
| `src/log.ts` | 日志工具 |
