Files
2026-05-16 13:24:02 +08:00

16 KiB
Raw Permalink Blame History

项目概述

**本文档引用的文件** - [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) - [client/public/bidirectional/js/main.js](file://client/public/bidirectional/js/main.js) - [client/public/onebyone/main.js](file://client/public/onebyone/main.js) - [client/src/peer.js](file://client/src/peer.js) - [client/src/sender.js](file://client/src/sender.js) - [package.json](file://package.json) - [client/package.json](file://client/package.json) - [src/log.ts](file://src/log.ts) - [src/class/options.ts](file://src/class/options.ts)

目录

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

简介

Video Socket Server 是一个基于 WebRTC 的实时双向视频通信服务端与前端示例项目支持两种信令模式WebSocket 与 HTTP 轮询)与两种通信模式(公共模式与私有模式)。项目旨在为 Unity Render Streaming、远程视频监控、在线教育等场景提供低延迟、高可靠性的视频传输基础设施。

  • 核心目标

    • 提供稳定可靠的 WebRTC 信令与媒体转发能力
    • 支持公共模式(广播式)与私有模式(点对点/一对多)
    • 提供 WebSocket 与 HTTP 两种信令通道,适配不同网络环境
    • 提供丰富的前端示例,覆盖双向视频通话、一对一通话、输入遥测等
  • 技术定位

    • 后端Node.js + TypeScript + Express.js
    • 前端:原生 JavaScriptES Modules结合 WebRTC API
    • 协议WebSocketws:// 或 wss://)与 HTTP RESTful 接口
    • 数据结构Offer/Answer 与 ICE Candidate 的信令封装
  • 主要应用场景

    • Unity Render Streaming通过 WebRTC 实现远端渲染画面的低延迟传输
    • 远程视频监控:支持多路摄像头与回放控制
    • 在线教育:支持课堂互动、屏幕共享与聊天

章节来源

项目结构

项目采用前后端分离的组织方式:

  • 后端src服务启动、HTTP 路由、WebSocket 信令、日志与配置
  • 前端client静态资源与示例页面包含多个演示场景双向视频、一对一通话、输入遥测等
graph TB
subgraph "后端(src)"
IDX["入口: index.ts"]
SRV["HTTP服务: server.ts"]
WS["WebSocket信令: websocket.ts"]
WSH["WS处理器: class/websockethandler.ts"]
HTH["HTTP处理器: class/httphandler.ts"]
SIG["信令路由: signaling.ts"]
LOG["日志: log.ts"]
OPT["配置: class/options.ts"]
end
subgraph "前端(client)"
PUB["静态资源: public/*"]
SRC["模块: src/*"]
end
IDX --> SRV
SRV --> SIG
SRV --> PUB
SRV --> SRC
SRV --> WS
WS --> WSH
SIG --> HTH
IDX --> LOG
IDX --> OPT

图表来源

章节来源

核心组件

  • 服务入口与启动

    • 解析命令行参数,创建 HTTP/HTTPS 服务器,根据配置选择信令模式
    • 启动 WebSocket 信令或 HTTP 轮询信令
  • HTTP 服务与静态资源

    • 提供 /config 接口返回运行配置(是否使用 WebSocket、启动模式、日志级别
    • 提供 /signaling 路由,挂载 HTTP 信令处理器
    • 提供静态页面与模块资源,首页自动指向 client/public/index.html
  • WebSocket 信令

    • 监听连接、消息、关闭事件解析多种信令类型connect/disconnect/offer/answer/candidate/broadcast/ping/pong/call-request/on-message
    • 将消息分派至 WS 处理器进行业务逻辑处理
  • WS 处理器1对多/私有模式)

    • 维护连接组host 与 participants支持广播与定向转发
    • 处理 offer/answer/candidate 的路由与转发,支持 participantId 标识
  • HTTP 信令处理器HTTP 轮询)

    • 提供会话管理与连接管理接口,支持轮询获取信令消息
    • 支持超时会话清理与断开连接记录
  • 日志与配置

    • 可配置日志级别,统一输出格式
    • Options 接口定义运行参数(端口、证书、信令类型、通信模式、日志级别)

章节来源

架构总览

系统采用“HTTP 服务 + WebSocket/HTTP 信令”的双信令架构,支持公共模式与私有模式两种通信策略。

graph TB
subgraph "客户端"
FE1["双向视频示例<br/>bidirectional/main.js"]
FE2["一对一通话示例<br/>onebyone/main.js"]
PEER["Peer类<br/>peer.js"]
SEND["输入遥测Sender<br/>sender.js"]
end
subgraph "服务端"
HTTP["HTTP服务<br/>server.ts"]
WS["WebSocket信令<br/>websocket.ts"]
WSH["WS处理器<br/>websockethandler.ts"]
HTH["HTTP处理器<br/>httphandler.ts"]
SIG["信令路由<br/>signaling.ts"]
end
FE1 --> |WebSocket/HTTP| HTTP
FE2 --> |WebSocket/HTTP| HTTP
HTTP --> SIG
HTTP --> WS
WS --> WSH
SIG --> HTH
FE1 --> PEER
FE2 --> PEER
FE1 --> SEND

图表来源

详细组件分析

WebSocket 信令流程(序列图)

展示客户端通过 WebSocket 发送/接收信令的典型流程。

sequenceDiagram
participant C as "客户端"
participant WS as "WebSocket服务器"
participant H as "WS处理器"
C->>WS : "connect" 连接建立
WS->>H : "onConnect(connectionId)"
H-->>C : "connect" {connectionId, role, participantId}
C->>WS : "offer" {connectionId, sdp}
WS->>H : "onOffer(ws, message)"
H-->>C : "offer" 转发/广播
C->>WS : "answer" {connectionId, sdp}
WS->>H : "onAnswer(ws, message)"
H-->>C : "answer" 转发/广播
C->>WS : "candidate" {connectionId, candidate, sdpMLineIndex, sdpMid}
WS->>H : "onCandidate(ws, message)"
H-->>C : "candidate" 转发/广播
C->>WS : "disconnect" {connectionId}
WS->>H : "onDisconnect(ws, connectionId)"
H-->>C : "disconnect" 通知

图表来源

章节来源

HTTP 信令轮询流程(序列图)

展示客户端通过 HTTP 轮询获取信令消息的流程。

sequenceDiagram
participant C as "客户端"
participant S as "HTTP服务"
participant R as "信令路由"
participant H as "HTTP处理器"
C->>S : "PUT /signaling" 创建会话
S->>R : "路由到 httphandler"
R->>H : "createSession()"
H-->>C : "{sessionId}"
C->>S : "PUT /signaling/connection" {connectionId}
S->>R : "路由到 httphandler"
R->>H : "createConnection()"
H-->>C : "{connectionId, polite}"
loop 轮询
C->>S : "GET /signaling/offer?fromtime=..."
S->>R : "路由到 httphandler"
R->>H : "getOffer(fromtime)"
H-->>C : "{offers}"
end
C->>S : "POST /signaling/offer" {sdp}
S->>R : "路由到 httphandler"
R->>H : "postOffer()"
H-->>C : "OK"
C->>S : "DELETE /signaling" 删除会话
S->>R : "路由到 httphandler"
R->>H : "deleteSession()"
H-->>C : "200"

图表来源

章节来源

前端组件与 WebRTC 集成

  • 双向视频示例bidirectional

    • 通过 RenderStreaming 管理连接,动态选择 WebSocket 或 HTTP 信令
    • 使用 Peer 类封装 RTCPeerConnection 生命周期与事件
    • 使用 Sender 类实现鼠标/键盘/手柄/触摸的输入遥测与数据通道发送
  • 一对一通话示例onebyone

    • 基于 store/UIRenderer 的状态管理与 UI 渲染
    • 支持通话请求、接听/拒接、媒体切换、录制控制等
classDiagram
class Peer {
+connectionId
+polite
+pc
+ontrack()
+ondatachannel()
+onicecandidate()
+onnegotiationneeded()
+getTransceivers()
+addTrack()
+addTransceiver()
+createDataChannel()
+getStats()
+onGotDescription()
+onGotCandidate()
}
class Sender {
+devices
+addMouse()
+addKeyboard()
+addGamepad()
+addTouchscreen()
+_queueStateEvent()
+_queueTextEvent()
}
class Observer {
+channel
+onNext(message)
}
Sender --> Observer : "通过数据通道发送"
Peer --> Sender : "配合输入遥测"

图表来源

章节来源

通信模式与连接组(流程图)

展示私有模式下的连接组管理与消息转发逻辑。

flowchart TD
Start(["进入 onConnect"]) --> CheckPrivate{"是否私有模式?"}
CheckPrivate --> |否| Public["公共模式: 创建连接组(若无)"]
CheckPrivate --> |是| Private["私有模式: host/参与者管理"]
Public --> BroadcastOffer["广播 offer 给其他客户端"]
Private --> HostCheck{"是否已有 host?"}
HostCheck --> |否| CreateHost["创建 host 并标记为 polite=false"]
HostCheck --> |是| AddParticipant["添加为 participant 并通知 host"]
OfferRoute{"消息来源角色"} --> |host| ToParticipants["转发给所有 participants"]
OfferRoute --> |participant| ToHost["转发给 host"]
AnswerRoute{"消息来源角色"} --> |host| ToTarget["转发给指定 participant"]
AnswerRoute --> |participant| ToHost2["转发给 host"]
CandidateRoute{"消息来源角色"} --> |host| ToParticipants2["转发给所有 participants"]
CandidateRoute --> |participant| ToHost3["转发给 host"]

图表来源

章节来源

依赖分析

  • 后端依赖

    • expressHTTP 服务框架
    • wsWebSocket 服务器
    • morganHTTP 访问日志
    • cors/multer跨域与文件上传
    • uuid会话 ID 生成
    • commander命令行参数解析
  • 前端依赖

    • Jest开发单元测试
    • ESLint开发代码规范
    • 浏览器原生 WebRTC API
graph LR
P["package.json"] --> E["express"]
P --> W["ws"]
P --> M["morgan"]
P --> C["cors"]
P --> U["uuid"]
P --> CMD["commander"]
CP["client/package.json"] --> J["jest"]
CP --> ESL["eslint"]

图表来源

章节来源

性能考虑

  • 信令模式选择

    • WebSocket低延迟、高吞吐适合实时交互
    • HTTP 轮询:兼容性更好,适合受限网络或代理环境
  • 通信模式选择

    • 私有模式host 与 participants 明确分离,便于控制与扩展
    • 公共模式:广播式转发,适合简单场景但需注意带宽与 CPU 开销
  • 日志与监控

    • 可配置日志级别,避免生产环境过度输出
    • 建议结合浏览器 WebRTC 统计 API 与服务端日志进行性能分析
  • 媒体参数

    • 合理设置分辨率、帧率与编解码器偏好,平衡画质与延迟

[本节为通用指导,无需具体文件分析]

故障排查指南

  • 启动与证书

    • HTTPS 启用需提供 server.key 与 server.cert可通过命令行参数指定路径
    • 若证书缺失,服务将以 HTTP 方式启动
  • 信令类型校验

    • 仅支持 websocket 与 http 两种类型;非法值会被重置为 websocket
  • WebSocket 心跳与断开

    • 服务器内置心跳检测ping/pong长时间无活动将触发断开
    • 客户端需正确处理断开事件并清理资源
  • HTTP 会话超时

    • 会话在指定时间内无请求将被清理,避免内存泄漏
    • 客户端应定期轮询或及时释放会话

章节来源

结论

Video Socket Server 提供了完整的 WebRTC 信令与媒体传输方案,具备灵活的信令与通信模式选择、清晰的前后端分离架构,以及丰富的前端示例。通过合理配置与优化,可在多种实际场景中实现高质量的实时视频通信。

[本节为总结性内容,无需具体文件分析]

附录

  • 快速启动

    • 开发模式:执行脚本 dev启动 HTTPS 服务,监听指定端口
    • 生产模式:构建后运行 build/index.js或使用打包工具
  • 常用接口

    • GET /config获取运行配置
    • GET /signaling/connection-ids获取所有连接 ID
    • PUT /signaling创建会话
    • PUT /signaling/connection创建连接
    • GET /signaling/offer|answer|candidate轮询获取信令
    • POST /signaling/offer|answer|candidate推送信令
    • DELETE /signaling删除会话

章节来源