# 开发指南

<cite>
**本文引用的文件**
- [package.json](file://package.json)
- [client/package.json](file://client/package.json)
- [tsconfig.json](file://tsconfig.json)
- [tsconfig.lint.json](file://tsconfig.lint.json)
- [jest.config.js](file://jest.config.js)
- [client/jest.config.js](file://client/jest.config.js)
- [client/jest.setup.js](file://client/jest.setup.js)
- [.eslintrc.cjs](file://.eslintrc.cjs)
- [client/.eslintrc.json](file://client/.eslintrc.json)
- [.editorconfig](file://.editorconfig)
- [run.bat](file://run.bat)
- [.gitignore](file://.gitignore)
- [src/index.ts](file://src/index.ts)
- [src/server.ts](file://src/server.ts)
- [src/class/options.ts](file://src/class/options.ts)
- [src/log.ts](file://src/log.ts)
- [test/httphandler.test.ts](file://test/httphandler.test.ts)
- [test/websockethandler.test.ts](file://test/websockethandler.test.ts)
</cite>

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

## 简介
本开发指南面向参与“视频流服务器”项目的开发者，目标是帮助你快速搭建本地开发环境、理解代码规范与编码标准、掌握调试与测试技巧、明确扩展开发流程、以及建立版本管理与发布流程的共识。项目采用 Node.js + TypeScript 构建，前端静态资源由服务端托管，支持 WebSocket 与 HTTP 两种信令模式，内置日志系统与 Swagger 文档。

## 项目结构
项目分为服务端与客户端两部分：
- 服务端（src）：Express 应用、HTTP 路由、WebSocket 信令、日志与配置等。
- 客户端（client）：静态页面与前端脚本，通过 /module 与 /uploads 等路由访问。

```mermaid
graph TB
subgraph "服务端(src)"
IDX["入口: index.ts"]
SRV["HTTP服务: server.ts"]
LOG["日志: log.ts"]
OPT["选项: class/options.ts"]
end
subgraph "客户端(client)"
PUB["静态资源: public/*"]
SRC["前端源码: src/*"]
end
IDX --> SRV
SRV --> PUB
SRV --> SRC
SRV --> LOG
IDX --> OPT
```

图表来源
- [src/index.ts:1-109](file://src/index.ts#L1-L109)
- [src/server.ts:1-90](file://src/server.ts#L1-L90)
- [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:1-109](file://src/index.ts#L1-L109)
- [src/server.ts:1-90](file://src/server.ts#L1-L90)

## 核心组件
- 入口与启动：命令行参数解析、HTTPS/HTTP 启动、信令类型选择、日志输出。
- HTTP 服务：CORS、JSON/URL 编码中间件、静态资源、Swagger 文档、头像上传接口。
- 日志系统：可配置的日志级别与格式化输出。
- 测试框架：Jest（服务端）、Jest + jsdom（客户端），覆盖 HTTP 与 WebSocket 信令逻辑。

章节来源
- [src/index.ts:1-109](file://src/index.ts#L1-L109)
- [src/server.ts:1-90](file://src/server.ts#L1-L90)
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
- [jest.config.js:1-196](file://jest.config.js#L1-L196)
- [client/jest.config.js:1-196](file://client/jest.config.js#L1-L196)

## 架构总览
下图展示从浏览器到服务端的典型请求链路，包括静态资源、信令与上传接口。

```mermaid
sequenceDiagram
participant Browser as "浏览器"
participant Express as "Express 应用(server.ts)"
participant Signaling as "信令(HTTP/WebSocket)"
participant FS as "文件系统(头像上传)"
Browser->>Express : GET /
Express-->>Browser : 返回首页(静态资源)
Browser->>Express : GET /config
Express-->>Browser : 返回运行配置
Browser->>Express : GET /signaling/*
Express->>Signaling : 转发至 HTTP 信令处理器
Browser->>Express : POST /api/upload/avatar
Express->>FS : 写入头像并重命名
FS-->>Express : 返回结果
Express-->>Browser : JSON 响应
```

图表来源
- [src/server.ts:25-87](file://src/server.ts#L25-L87)
- [src/index.ts:75-90](file://src/index.ts#L75-L90)

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

## 详细组件分析

### 启动与配置（index.ts）
- 支持命令行参数：端口、HTTPS 证书、信令类型、通信模式、日志级别。
- 自动检测本机 IPv4 地址并输出访问地址。
- 根据信令类型启动 HTTP 轮询或 WebSocket 信令服务。

```mermaid
flowchart TD
Start(["进程启动"]) --> ParseArgs["解析命令行参数"]
ParseArgs --> CreateApp["创建 Express 应用"]
CreateApp --> Mode{"是否启用 HTTPS?"}
Mode --> |是| HTTPS["读取密钥与证书并监听"]
Mode --> |否| HTTP["以 HTTP 监听"]
HTTPS --> DetectIP["检测本机 IPv4 地址"]
HTTP --> DetectIP
DetectIP --> SigType{"信令类型"}
SigType --> |websocket| WS["初始化 WebSocket 信令"]
SigType --> |http| HTTPSig["初始化 HTTP 轮询信令"]
WS --> Done(["完成"])
HTTPSig --> Done
```

图表来源
- [src/index.ts:14-105](file://src/index.ts#L14-L105)

章节来源
- [src/index.ts:1-109](file://src/index.ts#L1-L109)
- [src/class/options.ts:1-10](file://src/class/options.ts#L1-L10)

### HTTP 服务与静态资源（server.ts）
- 中间件：CORS、JSON、URL 编码、日志（Morgan）。
- 路由：
  - GET /config：返回运行配置（信令类型、模式、日志级别）。
  - /signaling：转发至信令模块。
  - 静态资源：/ 与 /module。
  - 上传接口：POST /api/upload/avatar，使用 Multer 存储并按用户 ID 重命名。
  - /uploads：公开头像目录。

```mermaid
flowchart TD
Req["请求进入"] --> CORS["CORS 允许所有来源"]
CORS --> Body["解析 JSON/URL 编码"]
Body --> Log{"日志级别允许?"}
Log --> |是| Morgan["Morgan 访问日志"]
Log --> |否| Skip["跳过日志"]
Morgan --> Routes["分发路由"]
Skip --> Routes
Routes --> Config["GET /config"]
Routes --> Signaling["GET/POST /signaling/*"]
Routes --> Static["静态资源: / 与 /module"]
Routes --> Upload["POST /api/upload/avatar"]
Routes --> PublicUploads["GET /uploads/*"]
```

图表来源
- [src/server.ts:14-89](file://src/server.ts#L14-L89)

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

### 日志系统（log.ts）
- 提供多级日志：none/error/warn/log/info。
- 可通过字符串解析日志级别。
- 输出包含时间戳与级别前缀。

章节来源
- [src/log.ts:1-51](file://src/log.ts#L1-L51)

### 测试与断言（Jest）
- 服务端测试：覆盖 HTTP 信令在 public/private 模式下的行为，含超时清理逻辑。
- 客户端测试：Jest + jsdom 环境，通过 setup 注入 fetch、TextEncoder/Decoder、RTCPeerConnection 等缺失对象。

章节来源
- [test/httphandler.test.ts:1-510](file://test/httphandler.test.ts#L1-L510)
- [test/websockethandler.test.ts:1-191](file://test/websockethandler.test.ts#L1-L191)
- [client/jest.setup.js:1-35](file://client/jest.setup.js#L1-L35)

## 依赖关系分析
- 语言与构建：TypeScript、ts-node、Jest、ESLint。
- Web 框架：Express、ws（WebSocket）、Multer（文件上传）。
- 文档：Swagger JSdoc、Swagger UI Express。
- 日志：Morgan。
- 工具：Commander（命令行解析）。

```mermaid
graph LR
Pkg["package.json 依赖"] --> TS["TypeScript 运行时"]
Pkg --> Express["Express"]
Pkg --> WS["ws"]
Pkg --> Mul["Multer"]
Pkg --> Swagger["Swagger UI Express"]
Pkg --> Morgan["Morgan"]
Pkg --> Cmdr["Commander"]
Pkg --> Jest["Jest"]
Pkg --> ESL["ESLint + TS 插件"]
```

图表来源
- [package.json:14-46](file://package.json#L14-L46)

章节来源
- [package.json:1-60](file://package.json#L1-L60)

## 性能考虑
- 上传路径：头像上传使用磁盘存储，建议在生产环境挂载独立持久卷并限制文件大小与类型。
- 日志级别：默认 info，可在高并发场景调低日志级别以减少 I/O。
- 静态资源：Express 静态托管适合开发，生产建议使用 CDN 或反向代理缓存。
- 信令：WebSocket 在高并发下优于 HTTP 轮询，建议优先使用 websocket 模式。

## 故障排查指南
- 启动失败（HTTPS 证书）：确认 server.key 与 server.cert 存在且可读；或禁用 HTTPS 并使用 HTTP。
- 无法访问 /uploads：确保 uploads 目录存在且可读写。
- 上传失败：检查 Multer 配置与权限，查看服务端错误日志。
- 测试失败（jsdom 缺失 API）：确保使用客户端 jest.config 的 setup 文件已加载。
- 超时会话未清理：检查 HTTP 信令测试中的超时轮询逻辑与清理触发点。

章节来源
- [src/server.ts:44-87](file://src/server.ts#L44-L87)
- [client/jest.setup.js:1-35](file://client/jest.setup.js#L1-L35)
- [test/httphandler.test.ts:194-309](file://test/httphandler.test.ts#L194-L309)

## 结论
本项目提供了清晰的服务端架构与完善的测试体系，支持 WebSocket 与 HTTP 两种信令模式，并内置日志与文档能力。遵循本文的开发与测试规范，可高效地进行功能扩展与维护。

## 附录

### 开发环境搭建步骤
- 安装 Node.js 与 npm（建议使用版本管理器以避免版本冲突）。
- 克隆仓库后，在根目录与 client 目录分别执行安装依赖命令。
- 准备 HTTPS 证书（可选）：若启用 HTTPS，需准备 server.key 与 server.cert。
- 使用提供的脚本启动开发服务或打包产物。

章节来源
- [package.json:5-12](file://package.json#L5-L12)
- [client/package.json:5-8](file://client/package.json#L5-L8)
- [run.bat:1-17](file://run.bat#L1-L17)

### 代码规范与编码标准
- 统一缩进与换行：EditorConfig 规定空格缩进、LF 换行、UTF-8 字符集。
- TypeScript 规范：ESLint 配置启用 @typescript-eslint 推荐规则，强制分号。
- JavaScript 规范（客户端）：ESLint 配置启用 jest 插件与推荐规则，强制分号。
- 代码风格：遵循 EditorConfig 与 ESLint 规则，保持一致的排版与语法。

章节来源
- [.editorconfig:10-20](file://.editorconfig#L10-L20)
- [.eslintrc.cjs:1-25](file://.eslintrc.cjs#L1-L25)
- [client/.eslintrc.json:1-23](file://client/.eslintrc.json#L1-L23)

### 调试技巧与开发工具
- 本地启动：使用开发脚本启动服务，自动监听 TypeScript 源码变化。
- 单元测试：使用 Jest 运行服务端与客户端测试，关注覆盖率与断言。
- 信令调试：根据运行日志确认信令类型与模式，必要时降低日志级别以便观察。
- 上传调试：通过 /uploads 访问上传后的头像，验证重命名与路径。

章节来源
- [package.json:5-12](file://package.json#L5-L12)
- [jest.config.js:1-196](file://jest.config.js#L1-L196)
- [client/jest.config.js:1-196](file://client/jest.config.js#L1-L196)
- [src/server.ts:62-87](file://src/server.ts#L62-L87)

### 扩展开发机制
- 新增 HTTP 路由：在 server.ts 中添加路由与处理逻辑，注意中间件顺序与错误处理。
- 新增 WebSocket 事件：在 WebSocket 信令模块中新增事件处理函数，并在测试中补充断言。
- 新增测试用例：在 test 目录下新增对应测试文件，复用现有的公共断言与模拟数据。
- 修改现有功能：遵循最小变更原则，先写测试，再实现修复或增强。

章节来源
- [src/server.ts:14-89](file://src/server.ts#L14-L89)
- [test/httphandler.test.ts:1-510](file://test/httphandler.test.ts#L1-L510)
- [test/websockethandler.test.ts:1-191](file://test/websockethandler.test.ts#L1-L191)

### 版本管理、分支策略与发布流程
- 版本号：项目使用语义化版本（package.json 中 version 字段）。
- 分支策略：建议采用 Git Flow，主分支用于稳定版本，开发分支用于迭代。
- 发布流程：本地构建（build）、测试（test）、打包（pack），生成可执行包或容器镜像后发布。

章节来源
- [package.json:2-4](file://package.json#L2-L4)
- [package.json:5-12](file://package.json#L5-L12)

### 贡献指南与代码审查标准
- 提交前：运行 lint 与 test，确保通过。
- 提交流程：提交变更到功能分支，发起 Pull Request，至少一名维护者审查。
- 代码审查要点：功能正确性、边界条件、错误处理、日志与安全、测试覆盖、性能影响。

章节来源
- [package.json:11-12](file://package.json#L11-L12)
- [jest.config.js:1-196](file://jest.config.js#L1-L196)
- [client/jest.config.js:1-196](file://client/jest.config.js#L1-L196)

### 常见问题与最佳实践
- 问题：浏览器跨域访问受限
  - 解决：服务端已启用 CORS，确保请求头与路径正确。
- 问题：WebSocket 连接失败
  - 解决：确认信令类型为 websocket，检查服务端日志与防火墙设置。
- 问题：头像上传失败
  - 解决：确认上传目录存在且可写，检查文件类型与大小限制。
- 最佳实践：在生产环境使用 HTTPS、CDN 加速静态资源、合理设置日志级别与轮询间隔。

章节来源
- [src/server.ts:22-24](file://src/server.ts#L22-L24)
- [src/server.ts:44-87](file://src/server.ts#L44-L87)
- [src/index.ts:55-74](file://src/index.ts#L55-L74)