Initiator 开始协商
接收到服务器中继的用户媒体消息后,发起者将再次激活 checkAndStart()
函数,由于边界条件现在已更改,因此这一次实际上已执行:通道已准备就绪,本地流已 由 getUserMedia()
API 调用提供。
图5-11 中的 UML 快照和以下 JavaScript 代码指示发起方(1)创建了 PeerConnection
对象; (2)将频道标记为已开始; (3)激活 doCall()
JavaScript 函数。
// Channel negotiation trigger function
function checkAndStart() {
if (!isStarted && typeof localStream != 'undefined' && isChannelReady) {
createPeerConnection();
isStarted = true;
if (isInitiator) {
doCall();
}
}
}
深入研究上述操作的详细信息,以下代码摘录显示,为正确管理 ICE 候选地址以及远程流的添加和删除,PeerConnection
对象附加了许多处理程序。
此外,PeerConnection
还配备了一个数据通道,该通道将用于以对等方式与 Joiner 交换文本数据:
function createPeerConnection() {
try {
pc = new RTCPeerConnection(pc_config, pc_constraints);
pc.addStream(localStream);
pc.onicecandidate = handleIceCandidate;
console.log('Created RTCPeerConnnection with:\n' + ' config: \'' + JSON.stringify(pc_config) + '\';\n' + ' constraints: \'' + JSON.stringify(pc_constraints) + '\'.');
} catch (e) {
console.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object.');
return;
}
pc.onaddstream = handleRemoteStreamAdded;
pc.onremovestream = handleRemoteStreamRemoved;
if (isInitiator) {
try {
// Create a reliable data channel
sendChannel = pc.createDataChannel("sendDataChannel",{reliable: true});
trace('Created send data channel');
} catch (e) {
alert('Failed to create data channel. ');
trace('createDataChannel() failed with exception: ' + e.message);
}
sendChannel.onopen = handleSendChannelStateChange;
sendChannel.onmessage = handleMessage;
sendChannel.onclose = handleSendChannelStateChange;
} else {
// Joiner
pc.ondatachannel = gotReceiveChannel;
}
}
图5-11 Initiator 开始协商
关于 doCall()
函数,它基本上在可用的 PeerConnection
上调用 createOffer()
方法,要求浏览器正确构建一个 SDP (会话描述协议)对象,该对象代表发起方的媒体和要传达给远程方的功能:
function doCall() {
console.log('Creating Offer...');
pc.createOffer(setLocalAndSendMessage, onSignalingError, sdpConstraints);
}
与此调用关联的成功处理程序负责将浏览器提供的 SDP 与 PeerConnection
相关联,并通过信令服务器将其传输到远程对等方:
function setLocalAndSendMessage(sessionDescription) {
pc.setLocalDescription(sessionDescription);
sendMessage(sessionDescription);
}
当前内容版权归 Salvatore Loreto & Simon Pietro Romano 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 Salvatore Loreto & Simon Pietro Romano .