Files
video_socket-server/.qoder/repowiki/zh/content/信令系统/HTTP 信令处理器.md
2026-05-16 13:24:02 +08:00

379 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HTTP 信令处理器
<cite>
**本文引用的文件**
- [src/class/httphandler.ts](file://src/class/httphandler.ts)
- [src/class/offer.ts](file://src/class/offer.ts)
- [src/class/answer.ts](file://src/class/answer.ts)
- [src/class/candidate.ts](file://src/class/candidate.ts)
- [src/signaling.ts](file://src/signaling.ts)
- [src/server.ts](file://src/server.ts)
- [src/index.ts](file://src/index.ts)
- [client/src/signaling.js](file://client/src/signaling.js)
- [test/httphandler.test.ts](file://test/httphandler.test.ts)
- [src/log.ts](file://src/log.ts)
- [src/class/options.ts](file://src/class/options.ts)
- [src/websocket.ts](file://src/websocket.ts)
- [src/class/websockethandler.ts](file://src/class/websockethandler.ts)
- [src/服务端接口与WebSocket消息类型.md](file://src/服务端接口与WebSocket消息类型.md)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概览](#架构概览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件为 HTTP 信令处理器的综合技术文档,重点阐述基于 HTTP 轮询的信令工作机制与实现细节。HTTP 信令通过一组 RESTful 接口实现会话管理、消息缓存与检索、以及客户端轮询拉取等核心能力。文档同时提供与 WebSocket 信令的对比分析,涵盖适用场景、性能特点、错误处理、超时管理与重试机制,并给出实际使用示例与最佳实践建议。
## 项目结构
该项目采用前后端分离的模块化组织方式HTTP 信令相关的核心代码位于以下位置:
- 服务器端核心处理器src/class/httphandler.ts
- 信令路由定义src/signaling.ts
- 服务器创建与中间件配置src/server.ts
- 应用入口与协议选择src/index.ts
- 客户端 HTTP 信令实现client/src/signaling.js
- 测试用例test/httphandler.test.ts
- 日志与配置src/log.ts、src/class/options.ts
- WebSocket 对比实现src/websocket.ts、src/class/websockethandler.ts
```mermaid
graph TB
subgraph "客户端"
C_Signaling["Signaling 类<br/>client/src/signaling.js"]
end
subgraph "服务器端"
S_Index["应用入口<br/>src/index.ts"]
S_Server["Express 服务器<br/>src/server.ts"]
S_Router["HTTP 路由<br/>src/signaling.ts"]
S_Handler["HTTP 处理器<br/>src/class/httphandler.ts"]
S_WS["WebSocket 信令<br/>src/websocket.ts"]
end
C_Signaling --> |"HTTP 轮询"| S_Router
S_Router --> S_Handler
S_Index --> S_Server
S_Server --> S_Router
S_Index --> S_WS
```
**图表来源**
- [src/index.ts:52-91](file://src/index.ts#L52-L91)
- [src/server.ts:14-42](file://src/server.ts#L14-L42)
- [src/signaling.ts:1-25](file://src/signaling.ts#L1-L25)
- [src/class/httphandler.ts:1112-1130](file://src/class/httphandler.ts#L1112-L1130)
- [client/src/signaling.js:30-91](file://client/src/signaling.js#L30-L91)
**章节来源**
- [src/index.ts:13-109](file://src/index.ts#L13-L109)
- [src/server.ts:14-90](file://src/server.ts#L14-L90)
- [src/signaling.ts:1-25](file://src/signaling.ts#L1-L25)
## 核心组件
- HTTP 信令处理器:负责会话管理、消息缓存与检索、连接配对、超时清理等核心逻辑。
- 数据模型类Offer、Answer、Candidate封装信令消息的数据结构。
- HTTP 路由层:定义 /signaling 下的 REST 接口,统一鉴权中间件与会话校验。
- 客户端轮询实现:基于 Fetch API 的轮询机制,按 fromtime 实现增量拉取。
- 测试框架:覆盖公共/私有模式下的会话生命周期、消息传递与超时清理。
**章节来源**
- [src/class/httphandler.ts:31-120](file://src/class/httphandler.ts#L31-L120)
- [src/class/offer.ts:1-11](file://src/class/offer.ts#L1-L11)
- [src/class/answer.ts:1-8](file://src/class/answer.ts#L1-L8)
- [src/class/candidate.ts:1-12](file://src/class/candidate.ts#L1-L12)
- [src/signaling.ts:6-24](file://src/signaling.ts#L6-L24)
- [client/src/signaling.js:30-91](file://client/src/signaling.js#L30-L91)
- [test/httphandler.test.ts:6-310](file://test/httphandler.test.ts#L6-L310)
## 架构概览
HTTP 信令的整体架构围绕“会话-连接-消息”三层结构展开:
- 会话Session通过 PUT /signaling 创建,携带 Session-Id 头进行后续请求鉴权。
- 连接Connection在会话内创建/删除,用于标识对端参与者。
- 消息Offer/Answer/Candidate在连接之间传递按 fromtime 实现增量拉取。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Router as "HTTP 路由<br/>src/signaling.ts"
participant Handler as "HTTP 处理器<br/>src/class/httphandler.ts"
Client->>Router : "PUT /signaling"
Router->>Handler : "createSession()"
Handler-->>Router : "{ sessionId }"
Router-->>Client : "返回 sessionId"
Client->>Router : "PUT /signaling/connection"
Router->>Handler : "createConnection()"
Handler-->>Router : "{ connectionId, polite }"
Router-->>Client : "返回连接信息"
Client->>Router : "GET /signaling?fromtime=..."
Router->>Handler : "getAll()/getOffer()/getAnswer()/getCandidate()"
Handler-->>Router : "合并后的消息数组"
Router-->>Client : "返回增量消息"
Client->>Router : "POST /signaling/offer|answer|candidate"
Router->>Handler : "postOffer()/postAnswer()/postCandidate()"
Handler-->>Router : "200 OK"
Router-->>Client : "确认接收"
```
**图表来源**
- [src/signaling.ts:15-22](file://src/signaling.ts#L15-L22)
- [src/class/httphandler.ts:664-675](file://src/class/httphandler.ts#L664-L675)
- [src/class/httphandler.ts:739-783](file://src/class/httphandler.ts#L739-L783)
- [src/class/httphandler.ts:615-641](file://src/class/httphandler.ts#L615-L641)
- [src/class/httphandler.ts:855-886](file://src/class/httphandler.ts#L855-L886)
- [src/class/httphandler.ts:913-952](file://src/class/httphandler.ts#L913-L952)
- [src/class/httphandler.ts:985-998](file://src/class/httphandler.ts#L985-L998)
## 详细组件分析
### 会话管理策略
- 会话创建:调用 createSession() 生成唯一 sessionId并初始化会话级映射连接集合、Offer/Answer/Candidate 缓存、断开连接记录)。
- 会话维护checkSessionId() 中更新 lastRequestedTime作为超时判断依据轮询接口 getAll()/getOffer()/getAnswer()/getCandidate() 均先触发超时检查。
- 会话销毁deleteSession() 删除会话及其所有连接_deleteConnection() 同步清理连接对、消息缓存与断开记录。
```mermaid
flowchart TD
Start(["开始"]) --> CreateSession["创建会话<br/>createSession()"]
CreateSession --> InitMaps["初始化会话映射"]
InitMaps --> Maintain["维护会话<br/>更新 lastRequestedTime"]
Maintain --> Poll["轮询接口<br/>getAll/getOffer/getAnswer/getCandidate"]
Poll --> TimeoutCheck{"是否超时?"}
TimeoutCheck --> |是| DeleteSession["删除会话<br/>deleteSession()"]
TimeoutCheck --> |否| Continue["继续处理"]
DeleteSession --> End(["结束"])
Continue --> End
```
**图表来源**
- [src/class/httphandler.ts:664-675](file://src/class/httphandler.ts#L664-L675)
- [src/class/httphandler.ts:128-145](file://src/class/httphandler.ts#L128-L145)
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
- [src/class/httphandler.ts:697-696](file://src/class/httphandler.ts#L697-L696)
- [src/class/httphandler.ts:153-194](file://src/class/httphandler.ts#L153-L194)
**章节来源**
- [src/class/httphandler.ts:128-145](file://src/class/httphandler.ts#L128-L145)
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
- [src/class/httphandler.ts:697-696](file://src/class/httphandler.ts#L697-L696)
- [src/class/httphandler.ts:153-194](file://src/class/httphandler.ts#L153-L194)
### 消息缓存机制
- Offer 缓存:以 sessionId -> connectionId -> Offer 映射存储,支持按 fromtime 过滤与跨会话(公共模式)广播。
- Answer 缓存:以 sessionId -> connectionId -> Answer 映射存储,公共模式下向配对会话广播。
- Candidate 缓存:以 sessionId -> connectionId -> Candidate[] 数组存储,按 fromtime 过滤Answer 到来时同步更新对应 Candidate 的时间戳。
- 断开连接记录:以 sessionId -> Disconnection[] 数组存储,支持按 fromtime 过滤。
```mermaid
classDiagram
class Offer {
+string sdp
+number datetime
+boolean polite
}
class Answer {
+string sdp
+number datetime
}
class Candidate {
+string candidate
+number sdpMLineIndex
+string sdpMid
+number datetime
}
class Disconnection {
+string id
+number datetime
}
class HTTPHandler {
+Map~string,Set~string~~ clients
+Map~string,number~ lastRequestedTime
+Map~string,Map~string,Offer~~ offers
+Map~string,Map~string,Answer~~ answers
+Map~string,Map~string,Candidate[]~~ candidates
+Map~string,Disconnection[]~~ disconnections
+Map~string,[string,string]~ connectionPair
}
HTTPHandler --> Offer : "缓存"
HTTPHandler --> Answer : "缓存"
HTTPHandler --> Candidate : "缓存"
HTTPHandler --> Disconnection : "记录"
```
**图表来源**
- [src/class/httphandler.ts:42-84](file://src/class/httphandler.ts#L42-L84)
- [src/class/offer.ts:1-11](file://src/class/offer.ts#L1-L11)
- [src/class/answer.ts:1-8](file://src/class/answer.ts#L1-L8)
- [src/class/candidate.ts:1-12](file://src/class/candidate.ts#L1-L12)
**章节来源**
- [src/class/httphandler.ts:58-84](file://src/class/httphandler.ts#L58-L84)
- [src/class/httphandler.ts:268-356](file://src/class/httphandler.ts#L268-L356)
- [src/class/httphandler.ts:941-951](file://src/class/httphandler.ts#L941-L951)
### 轮询接口设计与实现
- GET /signaling合并连接、断开、Offer、Answer、Candidate 消息,按 datetime 升序返回;支持 fromtime 过滤。
- GET /signaling/offer|answer|candidate分别返回对应类型消息支持 fromtime 过滤。
- GET /signaling/connection返回当前会话的连接列表。
- PUT /signaling创建会话返回 sessionId。
- DELETE /signaling删除会话。
- PUT|DELETE /signaling/connection创建/删除连接。
- POST /signaling/offer|answer|candidate提交信令消息。
客户端轮询流程:
- 首次启动PUT /signaling 获取 sessionId随后循环调用 GET /signaling 并解析消息类型分派事件。
- 增量拉取:使用上次响应中的 datetime 作为 fromtime避免重复接收历史消息。
```mermaid
sequenceDiagram
participant Client as "客户端<br/>client/src/signaling.js"
participant Server as "HTTP 服务器<br/>src/server.ts"
participant Router as "路由<br/>src/signaling.ts"
participant Handler as "处理器<br/>src/class/httphandler.ts"
Client->>Server : "PUT /signaling"
Server->>Router : "转发请求"
Router->>Handler : "createSession()"
Handler-->>Router : "{ sessionId }"
Router-->>Client : "返回 sessionId"
loop 轮询
Client->>Server : "GET /signaling?fromtime=..."
Server->>Router : "转发请求"
Router->>Handler : "getAll()"
Handler-->>Router : "messages + datetime"
Router-->>Client : "返回增量消息"
end
```
**图表来源**
- [src/server.ts:25-26](file://src/server.ts#L25-L26)
- [src/signaling.ts:15-16](file://src/signaling.ts#L15-L16)
- [src/class/httphandler.ts:615-641](file://src/class/httphandler.ts#L615-L641)
- [client/src/signaling.js:30-91](file://client/src/signaling.js#L30-L91)
**章节来源**
- [src/signaling.ts:9-22](file://src/signaling.ts#L9-L22)
- [src/class/httphandler.ts:398-407](file://src/class/httphandler.ts#L398-L407)
- [src/class/httphandler.ts:440-447](file://src/class/httphandler.ts#L440-L447)
- [src/class/httphandler.ts:492-501](file://src/class/httphandler.ts#L492-L501)
- [src/class/httphandler.ts:549-558](file://src/class/httphandler.ts#L549-L558)
- [src/class/httphandler.ts:615-641](file://src/class/httphandler.ts#L615-L641)
- [client/src/signaling.js:147-149](file://client/src/signaling.js#L147-L149)
### 与 WebSocket 信令的对比分析
- 适用场景
- HTTP 轮询适合受限网络环境NAT/防火墙)、代理服务器较多、无法建立长连接的场景。
- WebSocket适合实时性要求高、连接稳定、浏览器/移动端原生支持良好的场景。
- 性能特点
- HTTP 轮询:每次请求均为独立 TCP 连接,存在额外握手开销;但可利用 HTTP 缓存与代理优化。
- WebSocket单连接复用无握手开销延迟更低带宽利用率更高。
- 一致性与复杂度
- HTTP 轮询:需自行实现 fromtime 增量拉取与会话超时管理。
- WebSocket内置连接状态管理消息有序到达无需显式超时处理。
**章节来源**
- [src/服务端接口与WebSocket消息类型.md:533-542](file://src/服务端接口与WebSocket消息类型.md#L533-L542)
- [src/websocket.ts:15-39](file://src/websocket.ts#L15-L39)
- [src/class/websockethandler.ts](file://src/class/websockethandler.ts)
### 错误处理、超时管理与重试机制
- 会话超时:默认 10 秒未请求则自动清理会话;通过 _checkForTimedOutSessions() 触发。
- 连接冲突:私有模式下同一 connectionId 仅允许一次配对,重复使用返回 400。
- 请求校验checkSessionId() 未找到会话返回 404缺少必要字段返回 400。
- 客户端重试:客户端轮询间隔默认 1 秒,若未获取到 sessionId 会持续重试直至成功。
```mermaid
flowchart TD
A["收到请求"] --> B{"会话存在?"}
B --> |否| E["返回 404"]
B --> |是| C["更新 lastRequestedTime"]
C --> D{"是否超时?"}
D --> |是| F["清理会话并返回空消息"]
D --> |否| G["继续处理请求"]
```
**图表来源**
- [src/class/httphandler.ts:128-145](file://src/class/httphandler.ts#L128-L145)
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
- [test/httphandler.test.ts:29-33](file://test/httphandler.test.ts#L29-L33)
**章节来源**
- [src/class/httphandler.ts:31-32](file://src/class/httphandler.ts#L31-L32)
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
- [test/httphandler.test.ts:29-33](file://test/httphandler.test.ts#L29-L33)
- [test/httphandler.test.ts:363-379](file://test/httphandler.test.ts#L363-L379)
### 实际使用示例与最佳实践
- 客户端使用步骤
- 初始化 Signaling 实例,设置轮询间隔。
- 调用 start() 自动创建会话并进入轮询循环。
- 监听 disconnect/offer/answer/candidate 事件处理信令。
- 使用 createConnection()/deleteConnection() 管理连接。
- 使用 sendOffer()/sendAnswer()/sendCandidate() 发送信令。
- 最佳实践
- 合理设置轮询间隔(如 1-2 秒),平衡实时性与资源消耗。
- 使用 fromtime 实现增量拉取,避免重复处理历史消息。
- 在私有模式下确保 connectionId 的唯一性,避免 400 错误。
- 在受限网络环境下优先选择 HTTP 轮询,否则推荐 WebSocket。
**章节来源**
- [client/src/signaling.js:30-91](file://client/src/signaling.js#L30-L91)
- [client/src/signaling.js:99-138](file://client/src/signaling.js#L99-L138)
- [test/httphandler.test.ts:35-153](file://test/httphandler.test.ts#L35-L153)
## 依赖关系分析
- 服务器启动与协议选择index.ts 根据配置决定启用 HTTP 轮询还是 WebSocket。
- 服务器中间件server.ts 配置 CORS、JSON 解析、静态资源与 Swagger 文档。
- 路由与处理器signaling.ts 注册 HTTP 路由并挂载会话校验中间件,具体逻辑由 httphandler.ts 实现。
- 客户端依赖client/src/signaling.js 通过 Fetch API 与服务器交互。
```mermaid
graph LR
Index["src/index.ts"] --> Server["src/server.ts"]
Server --> Router["src/signaling.ts"]
Router --> Handler["src/class/httphandler.ts"]
Client["client/src/signaling.js"] --> Router
```
**图表来源**
- [src/index.ts:75-88](file://src/index.ts#L75-L88)
- [src/server.ts:25-41](file://src/server.ts#L25-L41)
- [src/signaling.ts:9-22](file://src/signaling.ts#L9-L22)
**章节来源**
- [src/index.ts:52-91](file://src/index.ts#L52-L91)
- [src/server.ts:14-90](file://src/server.ts#L14-L90)
- [src/signaling.ts:1-25](file://src/signaling.ts#L1-L25)
## 性能考虑
- 轮询频率:过高的轮询频率会增加服务器负载与网络开销;建议根据业务场景调整至 1-3 秒。
- fromtime 增量拉取:减少不必要的数据传输,降低带宽占用。
- 超时清理:及时释放闲置会话资源,避免内存泄漏。
- 缓存策略:合理控制消息缓存大小,避免长时间运行导致内存增长。
## 故障排除指南
- 404 会话不存在:确认客户端已成功创建会话并正确携带 Session-Id 头。
- 400 连接 ID 冲突:私有模式下同一 connectionId 已被使用,需更换或释放。
- 超时被清理:若长时间无请求,会话会被自动清理;可通过定期轮询维持会话活性。
- 增量消息缺失:检查 fromtime 参数是否正确传递,避免重复消费历史消息。
**章节来源**
- [src/class/httphandler.ts:128-145](file://src/class/httphandler.ts#L128-L145)
- [src/class/httphandler.ts:153-194](file://src/class/httphandler.ts#L153-L194)
- [test/httphandler.test.ts:29-33](file://test/httphandler.test.ts#L29-L33)
- [test/httphandler.test.ts:363-379](file://test/httphandler.test.ts#L363-L379)
## 结论
HTTP 信令处理器通过简洁的 REST 接口实现了完整的会话管理与消息缓存能力,结合客户端轮询机制满足了在受限网络环境下的信令需求。其与 WebSocket 的对比显示了在不同场景下的取舍WebSocket 更适合高实时性与高并发场景,而 HTTP 轮询则具备更好的兼容性与部署灵活性。配合 fromtime 增量拉取、超时清理与错误处理机制HTTP 信令可在多数实际应用中稳定运行。
## 附录
- 配置项说明secure、port、keyfile、certfile、typewebsocket/http、modepublic/private、logging。
- 日志级别none/error/warn/log/info默认 info。
**章节来源**
- [src/class/options.ts:1-10](file://src/class/options.ts#L1-L10)
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
- [src/index.ts:20-41](file://src/index.ts#L20-L41)