# 性能优化

<cite>
**本文引用的文件**
- [src/index.ts](file://src/index.ts)
- [src/server.ts](file://src/server.ts)
- [src/websocket.ts](file://src/websocket.ts)
- [src/class/websockethandler.ts](file://src/class/websockethandler.ts)
- [src/class/httphandler.ts](file://src/class/httphandler.ts)
- [src/signaling.ts](file://src/signaling.ts)
- [src/log.ts](file://src/log.ts)
- [client/src/signaling.js](file://client/src/signaling.js)
- [client/src/peer.js](file://client/src/peer.js)
- [client/src/sender.js](file://client/src/sender.js)
- [client/src/logger.js](file://client/src/logger.js)
- [client/public/js/stats.js](file://client/public/js/stats.js)
- [client/public/onebyone/store.js](file://client/public/onebyone/store.js)
- [client/src/memoryhelper.js](file://client/src/memoryhelper.js)
- [package.json](file://package.json)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本指南围绕视频流服务器与前端 WebRTC 客户端的整体性能进行系统化优化，覆盖以下方面：
- 内存管理优化：垃圾回收调优、内存泄漏检测与进程监控
- 并发处理优化：连接池配置、线程数调整、异步处理优化
- 资源限制设置：文件描述符、网络连接、CPU 使用率控制
- WebRTC 性能优化：编码参数、带宽自适应、网络质量监控
- 缓存策略：静态资源、API 响应、浏览器缓存
- 性能监控指标与基准测试方法

## 项目结构
该项目采用前后端分离的结构：
- 服务端基于 Express 提供 HTTP/WebSocket 信令与静态资源托管，同时支持 HTTPS
- 客户端包含多种示例页面与 WebRTC 输入/渲染相关脚本，以及统计与日志工具

```mermaid
graph TB
subgraph "服务端"
IDX["入口: src/index.ts"]
SRV["HTTP 服务器: src/server.ts"]
WS["WebSocket 信令: src/websocket.ts"]
WSH["WS 处理器: src/class/websockethandler.ts"]
HTTPH["HTTP 信令处理器: src/class/httphandler.ts"]
SIG["信令路由: src/signaling.ts"]
LOG["日志: src/log.ts"]
end
subgraph "客户端"
CLISIG["信令客户端: client/src/signaling.js"]
PEER["Peer 连接: client/src/peer.js"]
SENDER["输入发送: client/src/sender.js"]
STATS["统计: client/public/js/stats.js"]
STORE["质量分析: client/public/onebyone/store.js"]
LOGGER["日志: client/src/logger.js"]
end
IDX --> SRV
SRV --> WS
SRV --> SIG
WS --> WSH
SIG --> HTTPH
CLISIG --> |"WebSocket"| WS
CLISIG --> |"HTTP 轮询"| SRV
PEER --> |"WebRTC 统计"| STATS
PEER --> |"WebRTC 统计"| STORE
SENDER --> |"输入事件"| PEER
LOG -.->|"服务端日志级别"| SRV
LOGGER -.->|"客户端调试开关"| CLISIG
```

图表来源
- [src/index.ts:1-109](file://src/index.ts#L1-L109)
- [src/server.ts:1-90](file://src/server.ts#L1-L90)
- [src/websocket.ts:1-118](file://src/websocket.ts#L1-L118)
- [src/class/websockethandler.ts:1-479](file://src/class/websockethandler.ts#L1-L479)
- [src/class/httphandler.ts:1-800](file://src/class/httphandler.ts#L1-L800)
- [src/signaling.ts:1-25](file://src/signaling.ts#L1-L25)
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
- [client/src/signaling.js:1-292](file://client/src/signaling.js#L1-L292)
- [client/src/peer.js:1-188](file://client/src/peer.js#L1-L188)
- [client/src/sender.js:1-209](file://client/src/sender.js#L1-L209)
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
- [client/public/onebyone/store.js:1130-1380](file://client/public/onebyone/store.js#L1130-L1380)
- [client/src/logger.js:1-30](file://client/src/logger.js#L1-L30)

章节来源
- [src/index.ts:1-109](file://src/index.ts#L1-L109)
- [src/server.ts:1-90](file://src/server.ts#L1-L90)

## 核心组件
- 服务端启动与 HTTPS/HTTP 选择、日志级别、信令类型与运行模式
- Express 中间件链：CORS、JSON/URL 编码、静态资源、Swagger 文档
- WebSocket 信令服务器与处理器：连接生命周期、广播、1对多模式、心跳
- HTTP 信令轮询：会话管理、超时清理、消息队列（offer/answer/candidate）
- 客户端信令：WebSocket 与 HTTP 轮询双栈；WebRTC Peer 连接与统计
- 日志系统：服务端日志级别控制；客户端调试输出开关

章节来源
- [src/index.ts:13-109](file://src/index.ts#L13-L109)
- [src/server.ts:14-89](file://src/server.ts#L14-L89)
- [src/websocket.ts:6-118](file://src/websocket.ts#L6-L118)
- [src/class/websockethandler.ts:63-137](file://src/class/websockethandler.ts#L63-L137)
- [src/class/httphandler.ts:110-120](file://src/class/httphandler.ts#L110-L120)
- [src/signaling.ts:4-24](file://src/signaling.ts#L4-L24)
- [src/log.ts:15-24](file://src/log.ts#L15-L24)
- [client/src/signaling.js:30-97](file://client/src/signaling.js#L30-L97)
- [client/src/peer.js:37-82](file://client/src/peer.js#L37-L82)

## 架构总览
服务端通过 Express 提供 HTTP 接口与静态资源，WebSocket 作为实时信令通道；HTTP 轮询作为备用方案。客户端根据配置选择 WebSocket 或 HTTP 轮询进行信令交互，WebRTC 数据通道承载媒体与控制消息。

```mermaid
sequenceDiagram
participant C as "客户端"
participant S as "Express 服务器"
participant WS as "WebSocket 信令"
participant HTTP as "HTTP 信令"
participant H as "HTTP 处理器"
C->>S : "GET /config"
S-->>C : "{useWebSocket, mode, logging}"
alt "WebSocket 模式"
C->>WS : "建立连接"
WS-->>C : "connect"
C->>WS : "offer/answer/candidate/on-message"
WS->>WS : "路由/广播/心跳"
WS-->>C : "响应/广播"
else "HTTP 轮询模式"
C->>HTTP : "PUT /signaling (创建会话)"
HTTP-->>C : "{sessionId}"
loop "轮询"
C->>HTTP : "GET /signaling?fromtime=..."
HTTP->>H : "读取 offer/answer/candidate/disconnect"
H-->>HTTP : "聚合消息"
HTTP-->>C : "{messages, datetime}"
end
end
```

图表来源
- [src/server.ts:25-41](file://src/server.ts#L25-L41)
- [src/websocket.ts:27-115](file://src/websocket.ts#L27-L115)
- [src/class/httphandler.ts:615-641](file://src/class/httphandler.ts#L615-L641)
- [src/signaling.ts:6-24](file://src/signaling.ts#L6-L24)
- [client/src/signaling.js:30-97](file://client/src/signaling.js#L30-L97)

## 详细组件分析

### 服务端启动与运行模式
- 支持命令行参数：端口、HTTPS 证书、信令类型（websocket/http）、运行模式（public/private）、日志级别
- 自动选择 HTTP 或 HTTPS 监听，打印可用地址
- 信令类型校验与回退至默认值
- WebSocket 信令服务器初始化并注入运行模式

章节来源
- [src/index.ts:14-91](file://src/index.ts#L14-L91)

### HTTP 服务器与静态资源
- 开启 Morgan 日志（可配置）
- CORS 允许任意来源
- 解析 JSON/URL 编码请求体
- 提供 /config、/signaling 路由、静态资源目录
- Swagger 文档初始化
- 头像上传接口：multer 存储、重命名、返回相对 URL

章节来源
- [src/server.ts:18-89](file://src/server.ts#L18-L89)

### WebSocket 信令服务器
- 基于 ws 的服务器实例绑定到 HTTP 服务器
- 连接生命周期：add/remove
- 消息分发：connect/disconnect/offer/answer/candidate/ping/pong/broadcast/call-request/on-message
- 心跳机制（注释掉的实现），可通过处理器扩展

章节来源
- [src/websocket.ts:15-118](file://src/websocket.ts#L15-L118)
- [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430)

### WebSocket 处理器（1对多模式与广播）
- 私有模式：host 与多个 participants；offer/answer/candidate 按 participantId 路由
- 公共模式：全局广播
- 连接组管理：host/participants、参与者加入/离开通知
- 广播消息：支持按连接组或全局广播
- 心跳与超时（注释实现）

章节来源
- [src/class/websockethandler.ts:63-168](file://src/class/websockethandler.ts#L63-L168)
- [src/class/websockethandler.ts:175-206](file://src/class/websockethandler.ts#L175-L206)
- [src/class/websockethandler.ts:214-338](file://src/class/websockethandler.ts#L214-L338)
- [src/class/websockethandler.ts:370-402](file://src/class/websockethandler.ts#L370-L402)

### HTTP 信令处理器（轮询模式）
- 会话管理：创建/删除、连接集合、超时检测
- 消息存储：offer/answer/candidate 映射，断开连接记录
- 查询接口：/signaling、/offer、/answer、/candidate、/connection
- 私有模式下的连接配对与跨会话消息路由

章节来源
- [src/class/httphandler.ts:110-120](file://src/class/httphandler.ts#L110-L120)
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
- [src/class/httphandler.ts:398-407](file://src/class/httphandler.ts#L398-L407)
- [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)

### 客户端信令与 WebRTC
- WebSocketSignaling：连接建立、消息分发、发送 offer/answer/candidate/on-message
- HTTP 轮询 Signaling：循环拉取消息、事件派发
- Peer：RTCPeerConnection 生命周期、ICE 候选收集、状态变化监听、重发 offer
- Sender：鼠标/键盘/手柄/触摸输入采集与事件队列
- 统计：客户端侧统计计算（比特率、帧率、抖动、往返时间等）

章节来源
- [client/src/signaling.js:152-292](file://client/src/signaling.js#L152-L292)
- [client/src/signaling.js:30-97](file://client/src/signaling.js#L30-L97)
- [client/src/peer.js:37-82](file://client/src/peer.js#L37-L82)
- [client/src/peer.js:124-130](file://client/src/peer.js#L124-L130)
- [client/src/sender.js:14-188](file://client/src/sender.js#L14-L188)
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
- [client/public/onebyone/store.js:1130-1380](file://client/public/onebyone/store.js#L1130-L1380)

### 日志系统
- 服务端：枚举日志级别、动态设置、格式化输出
- 客户端：调试开关、条件输出

章节来源
- [src/log.ts:15-24](file://src/log.ts#L15-L24)
- [client/src/logger.js:3-29](file://client/src/logger.js#L3-L29)

## 依赖关系分析
- 服务端依赖：Express、ws、Morgan、Swagger、UUID、Multer
- 客户端依赖：浏览器原生 WebRTC API、EventTarget、fetch

```mermaid
graph LR
P["package.json 依赖"] --> E["Express"]
P --> W["ws"]
P --> M["Morgan"]
P --> SW["Swagger"]
P --> U["UUID"]
P --> MU["Multer"]
E --> SRV["src/server.ts"]
W --> WS["src/websocket.ts"]
SRV --> SIG["src/signaling.ts"]
SIG --> HTTPH["src/class/httphandler.ts"]
WS --> WSH["src/class/websockethandler.ts"]
```

图表来源
- [package.json:14-26](file://package.json#L14-L26)
- [src/server.ts:1-14](file://src/server.ts#L1-L14)
- [src/websocket.ts:1-6](file://src/websocket.ts#L1-L6)
- [src/signaling.ts:1-4](file://src/signaling.ts#L1-L4)
- [src/class/httphandler.ts:1-11](file://src/class/httphandler.ts#L1-L11)
- [src/class/websockethandler.ts:1-11](file://src/class/websockethandler.ts#L1-L11)

章节来源
- [package.json:14-26](file://package.json#L14-L26)

## 性能考虑

### 内存管理优化
- 垃圾回收调优
  - 服务端：合理设置 Node.js 堆大小与 GC 参数（通过环境变量或启动脚本传入），避免大对象频繁分配与长生命周期持有
  - 客户端：避免在事件回调中累积大量闭包引用；及时释放媒体轨道与数据通道
- 内存泄漏检测
  - 服务端：启用堆快照与内存采样，关注 Map/Set 的增长趋势（如连接组、会话映射）
  - 客户端：使用浏览器开发者工具的内存面板，检查事件监听器与 DOM 引用是否正确清理
- 进程监控
  - 服务端：定期记录内存使用、连接数、请求量；异常时触发重启或降级
  - 客户端：统计页面生命周期内的内存峰值与抖动

章节来源
- [src/class/websockethandler.ts:19-37](file://src/class/websockethandler.ts#L19-L37)
- [src/class/httphandler.ts:42-77](file://src/class/httphandler.ts#L42-L77)
- [client/src/peer.js:184-186](file://client/src/peer.js#L184-L186)

### 并发处理优化
- 连接池配置
  - 服务端：限制并发请求数与 WebSocket 连接数，结合负载均衡部署
  - 客户端：合理设置轮询间隔，避免过于频繁的短连接请求
- 线程数调整
  - Node.js：使用集群模式（cluster）或多进程部署，避免单进程阻塞
- 异步处理优化
  - 服务端：将耗时操作（文件写入、统计计算）放入任务队列或子线程
  - 客户端：WebRTC 统计与事件处理使用 requestAnimationFrame 或微任务

章节来源
- [src/server.ts:44-83](file://src/server.ts#L44-L83)
- [client/src/signaling.js:49-91](file://client/src/signaling.js#L49-L91)

### 资源限制设置
- 文件描述符限制
  - Linux：ulimit -n；Docker：--ulimit nofile；确保并发连接与文件上传场景充足
- 网络连接限制
  - 服务端：限制每 IP 的连接数与速率；启用反向代理限流
  - 客户端：合理设置轮询超时与重试次数
- CPU 使用率控制
  - 服务端：限制并发任务数量；对高 CPU 操作（编码/解码统计）做节流
  - 客户端：降低统计频率、减少不必要的事件派发

章节来源
- [src/server.ts:44-83](file://src/server.ts#L44-L83)
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)

### WebRTC 性能优化
- 编码参数调整
  - 服务端：通过信令协商合适的编解码器与参数（如分辨率、帧率、码率范围）
  - 客户端：根据网络质量动态调整发送轨道参数
- 带宽自适应
  - 使用 WebRTC 的 BWE 与 REMB；客户端周期性上报统计，服务端下发降级指令
- 网络质量监控
  - 客户端统计：比特率、帧率、抖动、丢包率、往返时间
  - 服务端：聚合统计与告警阈值

```mermaid
flowchart TD
Start(["开始"]) --> GetStats["获取 WebRTC 统计"]
GetStats --> Compute["计算比特率/帧率/抖动/丢包率"]
Compute --> Check{"是否异常?"}
Check --> |否| End(["结束"])
Check --> |是| Adapt["调整编码参数/带宽"]
Adapt --> SendCmd["通过信令下发降级指令"]
SendCmd --> End
```

图表来源
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
- [client/public/onebyone/store.js:1130-1380](file://client/public/onebyone/store.js#L1130-L1380)
- [client/src/peer.js:124-130](file://client/src/peer.js#L124-L130)

章节来源
- [client/src/peer.js:37-82](file://client/src/peer.js#L37-L82)
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
- [client/public/onebyone/store.js:1130-1380](file://client/public/onebyone/store.js#L1130-L1380)

### 缓存策略配置
- 静态资源缓存
  - Express 静态托管：设置合理的 Cache-Control 与 ETag
  - 前端构建产物：版本化文件名，长期缓存
- API 响应缓存
  - HTTP 信令：对只读查询设置短期缓存，结合 Last-Modified/ETag
- 浏览器缓存设置
  - 客户端脚本：强缓存；HTML：协商缓存
  - 服务端：通过中间件统一设置缓存头

章节来源
- [src/server.ts:27-28](file://src/server.ts#L27-L28)
- [src/server.ts:86](file://src/server.ts#L86)

### 性能监控指标与基准测试
- 指标
  - 服务端：QPS、P95/P99 延迟、连接数、内存、GC 次数与暂停时间
  - 客户端：首帧时间、卡顿次数、统计上报频率、丢包率、抖动
- 基准测试
  - 使用压测工具模拟多路并发；对比 WebSocket 与 HTTP 轮询的延迟与稳定性
  - WebRTC：不同分辨率/帧率组合下的端到端延迟与质量

章节来源
- [src/log.ts:15-24](file://src/log.ts#L15-L24)
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)

## 故障排查指南
- WebSocket 连接异常
  - 检查心跳实现与超时阈值；确认处理器中的连接移除逻辑
- HTTP 轮询堆积
  - 检查会话超时清理与消息去重；优化轮询间隔
- 内存泄漏
  - 关注 Map/Set 的清理时机；客户端事件监听器与 DOM 引用释放
- 日志定位
  - 调整日志级别；区分服务端与客户端日志输出

章节来源
- [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430)
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
- [src/log.ts:30-50](file://src/log.ts#L30-L50)
- [client/src/logger.js:3-29](file://client/src/logger.js#L3-L29)

## 结论
通过合理的内存管理、并发控制、资源限制与 WebRTC 统计监控，可在保证用户体验的同时提升系统的稳定性与吞吐能力。建议在生产环境中结合监控指标持续迭代优化策略，并针对不同部署场景（单机/集群/容器）制定差异化的性能基线。

## 附录
- 启动与配置
  - 服务端启动脚本与参数：端口、HTTPS、信令类型、运行模式、日志级别
  - 客户端信令选择：WebSocket 或 HTTP 轮询

章节来源
- [package.json:5-12](file://package.json#L5-L12)
- [src/index.ts:20-41](file://src/index.ts#L20-L41)
- [client/src/signaling.js:152-292](file://client/src/signaling.js#L152-L292)