1、WebRtcConnection 介绍
WebRtcConnection是进行webrtc协议交互的主要类,如:sdp解析与交互、Candidate信息交互、stream流管理、srtp包处理。
2、WebRtcConnection创建逻辑
代码见:licode\erizo_controller\erizoJS\models\Connection.js 的 _createWrtc()函数
wrtc = new addon.WebRtcConnection(threadPool, ioThreadPool, `spine_${configuration.sessionId}`,
global.config.erizo.stunserver, //stunserver相关信息
global.config.erizo.stunport,
global.config.erizo.minport,//最小端口、最大端口
global.config.erizo.maxport,
false,
JSON.stringify(global.mediaConfig),
global.config.erizo.useNicer,
global.config.erizo.useConnectionQualityCheck,
global.config.erizo.turnserver,
global.config.erizo.turnport,
global.config.erizo.turnusername,
global.config.erizo.turnpass,
global.config.erizo.networkinterface);
_createWrtc() {
const wrtc = new addon.WebRtcConnection(this.threadPool, this.ioThreadPool, this.id,
global.config.erizo.stunserver,
global.config.erizo.stunport,
global.config.erizo.minport,
global.config.erizo.maxport,
this.trickleIce,
Connection._getMediaConfiguration(this.mediaConfiguration),
global.config.erizo.useConnectionQualityCheck,
global.config.erizo.turnserver,
global.config.erizo.turnport,
global.config.erizo.turnusername,
global.config.erizo.turnpass,
global.config.erizo.networkinterface);
if (this.metadata) {
wrtc.setMetadata(JSON.stringify(this.metadata));
}
return wrtc;
}
streamId = `spine_${Math.floor(Math.random() * 1000)}`;
//创建媒体流
mediaStream = new addon.MediaStream(threadPool, wrtc,
streamId, config.label,
JSON.stringify(global.mediaConfig));
wrtc.addMediaStream(mediaStream);
that.createOffer = () => {
};
调用逻辑:
erizoJS.js 中创建ErizoJSController
const ejsController = controller.ErizoJSController(rpcID, threadPool, ioThreadPool);
ErizoJSController中每当添加Publisher和Subscriber时就会创建对应的client和连接connection。client创建的函数如下:
//首先判断该client是否存在,存在就返回对应的client,不存在就创建
const getOrCreateClient = (erizoControllerId, clientId, singlePC = false) => {
let client = clients.get(clientId);
if (client === undefined) {
client = new Client(erizoControllerId, erizoJSId, clientId,
threadPool, ioThreadPool, !!singlePC);
client.on('status_event', onConnectionStatusEvent.bind(this));
clients.set(clientId, client);
}
return client;
};
例如添加一个发布者
/*
* Adds a publisher to the room. This creates a new OneToManyProcessor
* and a new WebRtcConnection. This WebRtcConnection will be the publisher
* of the OneToManyProcessor.
*/
that.addPublisher = (erizoControllerId, clientId, streamId, options, callbackRpc) => {
updateUptimeInfo();
let publisher;
log.info('addPublisher, clientId', clientId, 'streamId', streamId);
//创建该发布者对应的client
const client = getOrCreateClient(erizoControllerId, clientId, options.singlePC);
if (publishers[streamId] === undefined) {
// eslint-disable-next-line no-param-reassign
options.publicIP = that.publicIP;
// eslint-disable-next-line no-param-reassign
options.privateRegexp = that.privateRegexp;
//创建对应的连接
const connection = client.getOrCreateConnection(options);
log.info('message: Adding publisher, ',
`clientId: ${clientId}, `,
`streamId: ${streamId}`,
logger.objectToLog(options),
logger.objectToLog(options.metadata));
publisher = new Publisher(clientId, streamId, connection, options);
publishers[streamId] = publisher;
publisher.initMediaStream();
publisher.on('callback', onAdaptSchemeNotify.bind(this, callbackRpc));
publisher.on('periodic_stats', onPeriodicStats.bind(this, streamId, undefined));
publisher.promise.then(() => {
connection.init(options.createOffer);
});
创建连接的函数:
getOrCreateConnection(options) {
let connection = this.connections.values().next().value;
log.info(`message: getOrCreateConnection, clientId: ${this.id}, singlePC: ${this.singlePc}`);
if (!this.singlePc || !connection) {
const id = this._getNewConnectionClientId();
connection = new Connection(this.erizoControllerId, id, this.threadPool,
this.ioThreadPool, this.id, options);
connection.on('status_event', this.emit.bind(this, 'status_event'));
this.addConnection(connection);
}
return connection;
}
创建连时会创建对应的WebRtcConnection。
具体的创建位置见Connection的构造函数,代码如下:
class Connection extends events.EventEmitter {
constructor(erizoControllerId, id, threadPool, ioThreadPool, clientId, options = {}) {
super();
log.info(`message: constructor, id: ${id}`);
this.id = id;
this.erizoControllerId = erizoControllerId;
this.clientId = clientId;
this.threadPool = threadPool;
this.ioThreadPool = ioThreadPool;
this.mediaConfiguration = 'default';
// {id: stream}
this.mediaStreams = new Map();
//此处就是创建WebrtcConnection的地方,
//这个函数就是文章开头提到的函数
this.wrtc = this._createWrtc();
}