3.1. 总体架构图与类图
3.1.1 系统架构图
Node.js 控制面 Channel C++ Worker 数据面 libuv 事件循环 ICE/DTLS 协商 RTP/RTCP 处理 媒体路由管理 Producer/Consumer API WebRTC 客户端 FFmpeg/GStreamer 集成 HTTP HLS 接口
- 双层架构:Node.js 层负责业务逻辑控制,C++ Worker 层处理媒体底层逻辑
- 通信桥梁 :
Channel和PayloadChannel实现跨进程通信 - 扩展能力:支持 WebRTC、RTP/RTCP 原生协议、FFmpeg 等多种接入方式
3.1.2 核心类图
1 1 1 N 1 N 1 1..N 1 1..N 1 1 1 1 Channel +emit(event, data) : void +on(event, handler) : void Router +createProducer() : Producer +createConsumer() : Consumer Producer +sendRtp(packet) : void +pause() : void +resume() : void Consumer +onRtp(packet) : void +requestKeyFrame() : void WebRtcTransport +connect(options) : void +produce(stream) : Producer +consume(producerId) : Consumer PayloadChannel +send(data) : void Worker
- 核心关系 :
Router是媒体流容器,通过WebRtcTransport连接客户端 - 数据传输 :
Producer/Consumer通过PayloadChannel发送大包数据 - 生命周期 :
Channel统一管理控制面事件,Worker 管理数据面实例
3.2. 信令交互模块
3.2.1 Channel 信令通信时序
JS Channel Worker emit('router.create', options) IPC发送消息 回复 routerId 触发 'router.created' 事件 JS Channel Worker
- JS 层调用
emit()发送创建房间请求 - Channel 通过 IPC 通道将消息传递给 Worker
- Worker 处理完底层逻辑后返回结果
- Channel 在 JS 层触发事件通知业务逻辑
源码说明(lib/Channel.js):
javascript
/**
* 信令通道核心类
* 负责 JS 层与 Worker 的双向通信
*/
class Channel {
/**
* 发送信令消息到 Worker
* @param {string} event - 事件名称
* @param {Object} data - 消息体
*/
emit(event, data) {
// 1. 构建消息对象
const message = {
event,
data
};
// 2. 通过 IPC 通道发送消息
this._worker.send(message);
}
/**
* 监听 Worker 返回的事件
* @param {string} event - 事件名称
* @param {Function} handler - 事件处理函数
*/
on(event, handler) {
if (!this._events[event]) {
this._events[event] = [];
}
// 3. 注册事件监听器
this._events[event].push(handler);
}
}
3.3. 路由器管理模块
3.3.1 Router 创建时序
JS Channel Worker emit('router.create', options) 创建 Router 请求 返回 routerId 触发 'router.created' 事件 JS Channel Worker
- JS 层调用
createRouter()发起创建请求 - Channel 转发请求到 Worker
- Worker 创建底层 C++ Router 实例
- 通过事件通知 JS 层创建完成
源码说明(lib/Router.js):
javascript
/**
* 房间管理类
* 对应底层 C++ 的 Router 实例
*/
class Router {
/**
* 创建房间实例
* @param {Channel} channel - 通信通道
* @param {Object} options - 创建参数
*/
constructor(channel, options) {
this._id = options.id || generateId();
// 1. 通过 Channel 发送创建请求
channel.emit('router.create', {
id: this._id,
options
});
// 2. 监听创建完成事件
channel.on('router.created', (routerId) => {
if (routerId === this._id) {
this._emit('created');
}
});
}
}
3.4. 生产者管理模块
3.4.1 Producer 创建时序
JS Channel Worker emit('producer.create', options) 创建 Producer 请求 返回 producerId 触发 'producer.created' 事件 JS Channel Worker
- JS 层调用
produce()创建生产者 - Channel 将请求转发给 Worker
- Worker 创建底层 C++ Producer
- 通过事件通知 JS 层创建完成
源码说明(lib/Producer.js):
javascript
/**
* 媒体生产者类
* 负责将媒体流推送到房间
*/
class Producer {
/**
* 创建生产者实例
* @param {Channel} channel - 通信通道
* @param {string} routerId - 所属房间ID
* @param {Object} options - 创建参数
*/
constructor(channel, routerId, options) {
this._id = options.id || generateId();
// 1. 发送创建请求
channel.emit('producer.create', {
routerId,
producerId: this._id,
options
});
// 2. 监听关闭事件
channel.on('producer.closed', (producerId) => {
if (producerId === this._id) {
this._emit('close');
}
});
}
}
3.5. 消费者管理模块
3.5.1 Consumer 创建时序
JS Channel Worker emit('consumer.create', options) 创建 Consumer 请求 返回 consumerId 触发 'consumer.created' 事件 JS Channel Worker
- JS 层调用
createConsumer()创建消费者 - Channel 转发请求到 Worker
- Worker 创建底层 C++ Consumer
- 通过事件通知 JS 层创建完成
源码说明(lib/Consumer.js):
javascript
/**
* 媒体消费者类
* 负责接收并消费媒体流
*/
class Consumer {
/**
* 创建消费者实例
* @param {Channel} channel - 通信通道
* @param {string} routerId - 所属房间ID
* @param {string} producerId - 对应生产者ID
*/
constructor(channel, routerId, producerId) {
this._id = generateId();
// 1. 发送创建请求
channel.emit('consumer.create', {
routerId,
producerId,
consumerId: this._id
});
// 2. 监听 RTP 包事件
channel.on('consumer.rtp', (consumerId, packet) => {
if (consumerId === this._id) {
this._emit('rtp', packet);
}
});
}
}
3.6. 数据通道模块
3.6.1 WebRtcTransport 连接时序
JS Channel Worker emit('transport.connect', options) 连接请求 返回连接状态 触发 'transport.connected' 事件 JS Channel Worker
- JS 层调用
connect()建立传输通道 - Channel 将 DTLS 参数传递给 Worker
- Worker 完成 ICE/DTLS 协商
- 通过事件通知 JS 层连接建立成功
源码说明(lib/WebRtcTransport.js):
javascript
/**
* WebRTC 传输通道类
* 负责媒体传输的底层连接
*/
class WebRtcTransport {
/**
* 建立连接
* @param {Object} options - 连接参数(包含 DTLS 参数)
*/
connect(options) {
// 1. 通过 Channel 发送连接请求
this._channel.emit('transport.connect', {
transportId: this._id,
options
});
// 2. 监听连接完成事件
this._channel.on('transport.connected', (transportId) => {
if (transportId === this._id) {
this._emit('connected');
}
});
}
}
3.7. 控制面与数据面交互
3.7.1 RTP 包传输时序
Producer WebRtcTransport Channel Worker sendRtp(packet) emit('transport.sendRtp', packet) 传输 RTP 包 (ACK) 'transport.rtpSent' Producer WebRtcTransport Channel Worker
- Producer 调用
sendRtp()发送 RTP 包 - 通过 WebRtcTransport 传递到 Channel
- Channel 使用 PayloadChannel 传输大包
- Worker 处理后返回确认信息
源码说明(lib/PayloadChannel.js):
javascript
/**
* 大包传输通道
* 优化 RTP 包的传输效率
*/
class PayloadChannel {
/**
* 发送大包数据
* @param {ArrayBuffer} data - 待发送数据
*/
send(data) {
// 1. 使用 UDP 套接字发送
this._socket.send(
data,
0,
data.byteLength,
this._port,
this._host
);
}
}
3.8. 完整业务流程
3.8.1 端到端媒体传输流程
Camera Producer WebRtcTransport Consumer Decoder captureFrame() sendRtp(packet) receiveRtp(packet) decode(packet) render(frame) Camera Producer WebRtcTransport Consumer Decoder
- 摄像头采集帧数据
- Producer 打包为 RTP 包
- 通过 WebRtcTransport 传输
- Consumer 接收并解码
- 最终渲染显示
3.9. 关键设计
| 模块 | 核心价值 | 代码体现 |
|---|---|---|
| 信令交互 | 解耦业务逻辑 | Channel.js 的事件驱动模型 |
| 路由管理 | 隔离媒体拓扑 | Router.js 的房间隔离机制 |
| 生产者管理 | 流量控制 | Producer.js 的 pause/resume 实现 |
| 消费者管理 | QoS 保障 | Consumer.js 的 NackGenerator 集成 |
| 数据通道 | 低延迟传输 | PayloadChannel.js 的 UDP 优化 |