md文档上传
This commit is contained in:
561
WebApp/src/服务端接口与WebSocket消息类型.md
Normal file
561
WebApp/src/服务端接口与WebSocket消息类型.md
Normal file
@@ -0,0 +1,561 @@
|
|||||||
|
# 服务端接口与 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` | 日志工具 |
|
||||||
Reference in New Issue
Block a user