# WebSocket 服务器 **本文引用的文件** - [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/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/log.ts](file://src/log.ts) - [src/signaling.ts](file://src/signaling.ts) - [src/swagger.ts](file://src/swagger.ts) - [client/src/signaling.js](file://client/src/signaling.js) - [package.json](file://package.json) - [test/websockethandler.test.ts](file://test/websockethandler.test.ts) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本技术文档围绕 WebSocket 服务器模块进行深入解析,重点覆盖以下方面: - WebSocket 服务器的创建与配置(含 HTTPS/WSS、日志与启动流程) - 连接生命周期管理(连接建立、断开、广播、消息路由) - WSSignaling 类的职责与实现要点(事件监听、消息分发、心跳与超时) - WebSocketHandler 的核心能力(连接组模型、1对多/多对多路由、广播机制) - 连接调试与监控方法(日志级别、Swagger 文档、心跳检测) - 连接池管理、心跳检测与断线重连策略 ## 项目结构 后端采用 Express 提供 HTTP/HTTPS 服务与静态资源,WebSocket 信令在独立模块中运行;同时保留 HTTP 轮询信令作为备选方案。 ```mermaid graph TB subgraph "服务端进程" A["Express 应用
src/server.ts"] B["HTTP(S) 服务器
src/index.ts"] C["WebSocket 信令服务器
src/websocket.ts"] D["WebSocket 处理器
src/class/websockethandler.ts"] E["HTTP 信令路由
src/signaling.ts"] F["Swagger 文档
src/swagger.ts"] end subgraph "客户端" G["浏览器/前端页面
client/public"] H["信令客户端封装
client/src/signaling.js"] end H --> |"WebSocket"| C H --> |"HTTP 轮询"| E B --> |"创建/绑定"| C A --> |"挂载路由/静态资源"| G A --> |"注册 HTTP 信令路由"| E A --> |"初始化 Swagger"| F ``` 图表来源 - [src/index.ts:52-91](file://src/index.ts#L52-L91) - [src/server.ts:14-42](file://src/server.ts#L14-L42) - [src/websocket.ts:15-116](file://src/websocket.ts#L15-L116) - [src/signaling.ts:4-24](file://src/signaling.ts#L4-L24) - [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65) 章节来源 - [src/index.ts:13-109](file://src/index.ts#L13-L109) - [src/server.ts:14-90](file://src/server.ts#L14-L90) - [src/websocket.ts:6-118](file://src/websocket.ts#L6-L118) - [src/signaling.ts:1-25](file://src/signaling.ts#L1-L25) - [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65) ## 核心组件 - WSSignaling:WebSocket 信令服务器入口,负责监听连接、消息解析与分发至 WebSocketHandler。 - WebSocketHandler:核心业务逻辑,维护连接组、1对多/多对多路由、广播、心跳与断线清理。 - 数据模型:Offer、Answer、Candidate 用于封装信令数据。 - 日志系统:统一日志级别控制与输出格式。 - HTTP 信令路由:保留 HTTP 轮询信令通道,便于兼容与调试。 - Swagger 文档:自动生成 API 文档,支持会话认证与信令接口说明。 章节来源 - [src/websocket.ts:6-118](file://src/websocket.ts#L6-L118) - [src/class/websockethandler.ts:1-479](file://src/class/websockethandler.ts#L1-L479) - [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/log.ts:1-51](file://src/log.ts#L1-L51) - [src/signaling.ts:1-25](file://src/signaling.ts#L1-L25) - [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65) ## 架构总览 WebSocket 服务器在 HTTP(S) 之上提供实时信令通道,客户端可通过 WebSocket 或 HTTP 轮询两种方式接入。WebSocket 信令以“连接组”为核心组织多端通信,支持广播与定向转发。 ```mermaid sequenceDiagram participant Client as "客户端
client/src/signaling.js" participant WS as "WSSignaling
src/websocket.ts" participant Handler as "WebSocketHandler
src/class/websockethandler.ts" Client->>WS : "WebSocket 连接建立" WS->>Handler : "add(ws)" WS-->>Client : "connect 消息role/polite/participantId" Client->>WS : "发送信令消息offer/answer/candidate/on-message/broadcast" WS->>Handler : "根据消息类型分发" Handler-->>Client : "转发/广播结果含 participantId" Client-->>WS : "断开连接/心跳 ping/pong" WS->>Handler : "remove(ws)/心跳检测" ``` 图表来源 - [src/websocket.ts:27-116](file://src/websocket.ts#L27-L116) - [src/class/websockethandler.ts:72-137](file://src/class/websockethandler.ts#L72-L137) - [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430) - [client/src/signaling.js:152-292](file://client/src/signaling.js#L152-L292) ## 详细组件分析 ### WSSignaling 类 职责与行为: - 接收 HTTP 服务器实例,创建 ws.Server 并绑定到同一端口。 - 注册 connection 事件:为新连接调用处理器 add,并在关闭时 remove。 - 注册 message 事件:解析 JSON 消息,按 type 分发到对应处理器(connect/disconnect/offer/answer/candidate/ping/pong/broadcast/on-message/call-request)。 - 内置 ping/pong 心跳:收到 ping 回复 pong,收到 pong 更新 lastActivity;注释掉的心跳定时器可在需要时启用。 实现要点: - 模式切换:通过 reset(mode) 设置 isPrivate,影响连接组与路由行为。 - 消息格式:支持 participantId 字段以区分多参与者场景。 - 日志:统一通过 log 输出接收到的消息与关键事件。 章节来源 - [src/websocket.ts:6-118](file://src/websocket.ts#L6-L118) - [src/class/websockethandler.ts:63-66](file://src/class/websockethandler.ts#L63-L66) ### WebSocketHandler 核心功能 - 连接组模型:Map,每个连接组包含 host 与多个 participants。 - 连接管理:add/remove 维护 clients 映射与连接组;onConnect/onDisconnect 实现 1对多/多对多角色分配。 - 信令路由: - offer/answer/candidate:host 与 participants 之间双向转发;私有模式下支持按 participantId 精确路由。 - broadcast:支持全局广播与按连接组广播。 - on-message:支持聊天消息等扩展消息的组内转发。 - 心跳与超时:提供心跳初始化/清理函数,注释掉的定时器默认不启用;可按需开启。 - 辅助能力:获取所有连接组 ID、判断是否 host、组内广播工具。 ```mermaid classDiagram class WSSignaling { +server +wss +constructor(server, mode) } class WebSocketHandler { +reset(mode) +add(ws) +remove(ws) +onConnect(ws, connectionId) +onDisconnect(ws, connectionId) +onOffer(ws, message) +onAnswer(ws, message) +onCandidate(ws, message) +onBroadcast(ws, message) +onMessage(ws, message) +AddHeartbeat(ws, connectionId) +RemoveHeartbeat(ws) +isHost(ws, connectionId) +broadcastToGroup(connectionId, senderWs, message) } WSSignaling --> WebSocketHandler : "消息分发" ``` 图表来源 - [src/websocket.ts:6-118](file://src/websocket.ts#L6-L118) - [src/class/websockethandler.ts:63-479](file://src/class/websockethandler.ts#L63-L479) 章节来源 - [src/class/websockethandler.ts:139-206](file://src/class/websockethandler.ts#L139-L206) - [src/class/websockethandler.ts:208-338](file://src/class/websockethandler.ts#L208-L338) - [src/class/websockethandler.ts:340-402](file://src/class/websockethandler.ts#L340-L402) - [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430) ### 数据模型 - Offer:封装 SDP、时间戳与是否“polite”标记。 - Answer:封装 SDP 与时间戳。 - Candidate:封装 ICE 候选项与 SDP 元信息及时间戳。 章节来源 - [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) ### 启动与配置 - 命令行参数:端口、HTTPS 开关与证书、信令类型(websocket/http)、通信模式(public/private)、日志级别。 - HTTPS:当 secure=true 时使用 server.key/server.cert 创建 https.Server。 - 信令类型:type=websocket 时启动 WSSignaling;否则提示并回退为 websocket。 - 日志:统一通过 log 模块输出启动信息与运行日志。 章节来源 - [src/index.ts:14-109](file://src/index.ts#L14-L109) - [src/log.ts:1-51](file://src/log.ts#L1-L51) ### HTTP 信令与 Swagger - HTTP 信令路由:提供会话管理与信令 CRUD 接口,支持会话认证(session-id)。 - Swagger:自动扫描 httphandler.ts 与 signaling.ts,生成 API 文档,支持会话认证与信令接口说明。 章节来源 - [src/signaling.ts:1-25](file://src/signaling.ts#L1-L25) - [src/class/httphandler.ts:1112-1130](file://src/class/httphandler.ts#L1112-L1130) - [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65) ## 依赖关系分析 - 运行时依赖:ws(WebSocket)、express(HTTP)、morgan(日志)、swagger-ui-express(文档)、uuid(会话 ID)。 - 构建与测试:TypeScript、Jest、ESLint、ts-jest 等。 - 客户端:浏览器通过 WebSocket 或 HTTP 轮询与服务端交互。 ```mermaid graph LR P["package.json 依赖声明"] --> WS["ws"] P --> EXP["express"] P --> MORGAN["morgan"] P --> SWG["swagger-ui-express"] P --> UUID["uuid"] IDX["src/index.ts"] --> SRV["src/server.ts"] IDX --> WSC["src/websocket.ts"] WSC --> WSH["src/class/websockethandler.ts"] SRV --> SIG["src/signaling.ts"] SRV --> SWG ``` 图表来源 - [package.json:14-46](file://package.json#L14-L46) - [src/index.ts:7-11](file://src/index.ts#L7-L11) - [src/server.ts:5-9](file://src/server.ts#L5-L9) - [src/websocket.ts:1-4](file://src/websocket.ts#L1-L4) - [src/class/websockethandler.ts:5-8](file://src/class/websockethandler.ts#L5-L8) - [src/signaling.ts:1-3](file://src/signaling.ts#L1-L3) - [src/swagger.ts:5-9](file://src/swagger.ts#L5-L9) 章节来源 - [package.json:14-60](file://package.json#L14-L60) - [src/index.ts:7-11](file://src/index.ts#L7-L11) - [src/server.ts:5-9](file://src/server.ts#L5-L9) - [src/websocket.ts:1-4](file://src/websocket.ts#L1-L4) - [src/class/websockethandler.ts:5-8](file://src/class/websockethandler.ts#L5-L8) - [src/signaling.ts:1-3](file://src/signaling.ts#L1-L3) - [src/swagger.ts:5-9](file://src/swagger.ts#L5-L9) ## 性能考量 - 连接组规模:每组 participants 使用 Set 存储,查找与删除均为 O(1),适合中小规模并发。 - 广播策略:组内广播遍历 participants,建议限制单组成员数量或引入分区策略。 - 心跳检测:当前注释掉定时器,避免不必要的 CPU 占用;如启用需合理设置周期与超时阈值。 - 日志级别:生产环境建议提升日志级别,减少高频日志输出对性能的影响。 - HTTPS 证书:WSS 需要正确配置证书与密钥,确保握手与传输安全。 ## 故障排查指南 - 启动与网络 - 确认端口占用与防火墙放行。 - HTTPS 模式检查 server.key 与 server.cert 是否存在且可读。 - WebSocket 连接 - 检查客户端 WebSocket URL(ws/wss)与主机一致。 - 观察浏览器开发者工具 Network 面板中的 WebSocket 握手与帧。 - 信令消息 - 使用 Swagger 文档校验 HTTP 信令接口(PUT/GET/POST/DELETE)参数与会话 ID。 - 对照客户端 signaling.js 的消息构造与事件派发。 - 日志定位 - 调整日志级别(info/warn/error/log),关注连接建立、断开、广播与路由关键节点。 - 自动化测试 - 参考单元测试用例,验证 public/private 模式下的连接、offer/answer/candidate 转发与广播行为。 章节来源 - [src/index.ts:55-88](file://src/index.ts#L55-L88) - [src/log.ts:11-51](file://src/log.ts#L11-L51) - [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65) - [client/src/signaling.js:152-292](file://client/src/signaling.js#L152-L292) - [test/websockethandler.test.ts:1-191](file://test/websockethandler.test.ts#L1-L191) ## 结论 该 WebSocket 服务器模块以简洁清晰的职责划分实现了 WebRTC 信令的核心需求:支持 WebSocket 与 HTTP 两种信令通道、基于连接组的 1对多/多对多路由、广播与定向转发、以及可扩展的消息类型。通过日志与 Swagger 的配合,具备良好的可观测性与可维护性。建议在高并发场景下进一步优化广播与心跳策略,并完善断线重连与幂等处理。 ## 附录 ### WebSocket 连接调试与监控 - 浏览器开发者工具:Network 面板查看握手、帧与错误。 - Swagger 文档:访问 /api-docs,使用 session-id 头部进行认证,查看 HTTP 信令接口。 - 日志:通过命令行参数设置日志级别,观察连接、断开、广播与路由事件。 - 心跳:若启用心跳定时器,注意 ping/pong 的周期与超时阈值配置。 章节来源 - [src/swagger.ts:16-65](file://src/swagger.ts#L16-L65) - [src/log.ts:11-51](file://src/log.ts#L11-L51) - [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430) ### 连接池管理、心跳检测与断线重连 - 连接池管理:clients 与 connectionGroup 维护连接映射与组关系,remove 时清理并广播断开事件。 - 心跳检测:提供 AddHeartbeat/RemoveHeartbeat,当前代码注释掉定时器;可按需启用。 - 断线重连:客户端应实现指数退避与自动重连逻辑;服务端在断开时通知组内成员并清理资源。 章节来源 - [src/class/websockethandler.ts:115-137](file://src/class/websockethandler.ts#L115-L137) - [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430) - [client/src/signaling.js:230-241](file://client/src/signaling.js#L230-L241)