RTCPeerConnection API是每个浏览器之间对等连接的核心.要创建RTCPeerConnection对象,只需编写
var pc = RTCPeerConnection(config);
其中 config 参数至少包含key,iceServers.它是一个URL对象数组,包含有关STUN和TURN服务器的信息,在查找ICE候选项时使用.您可以在代码中找到可用的公共STUN服务器列表.google.com
根据您是调用者还是被调用者,RTCPeerConnection对象在连接的每一侧以稍微不同的方式使用.
以下是用户流量和减号的示例;
注册 onicecandidate 处理程序.它会在收到任何ICE候选人时将其发送给另一个同行.
注册消息处理程序.您的信令服务器还应具有从其他对等方接收的消息的处理程序.如果消息包含 RTCSessionDescription 对象,则应使用 setRemoteDescription()方法将其添加到 RTCPeerConnection 对象.如果消息包含 RTCIceCandidate 对象,则应使用 addIceCandidate()方法将其添加到 RTCPeerConnection 对象.
利用 getUserMedia()设置本地媒体流,并使用 addStream将其添加到 RTCPeerConnection 对象()方法.
开始提供/回答谈判过程.这是调用者的流量与被调用者的流量不同的唯一步骤.调用者使用 createOffer()方法开始协商,并注册接收 RTCSessionDescription 对象的回调.然后,此回调应使用 setLocalDescription()将此 RTCSessionDescription 对象添加到 RTCPeerConnection 对象.最后,调用者应使用信令服务器将此 RTCSessionDescription 发送到远程对等方.另一方面,被调用者注册相同的回调,但是在 createAnswer()方法中.请注意,只有在从调用者收到商品后才会启动被调用者流程.
RTCPeerConnection API
属性
RTCPeerConnection.iceConnectionState(只读) : 返回描述连接状态的RTCIceConnectionState枚举.此值更改时会触发iceconnectionstatechange事件.可能的值 :
new : ICE代理正在等待远程候选人或收集地址
检查 : ICE代理有远程候选人,但尚未找到连接
已连接 : ICE代理已找到可用的连接,但仍在检查更远的候选者以获得更好的连接.
已完成 : ICE代理已找到可用的连接并停止测试远程候选人.
失败 : ICE代理检查了所有远程候选人,但没有找到至少一个组件的匹配.
已断开连接 : 至少有一个组件不再存在.
已关闭 : ICE代理已关闭.
RTCPeerConnection.iceGatheringState(只读) : 返回描述连接的ICE收集状态的RTCIceGatheringState枚举 :
new : 该对象刚刚创建.
收集 : ICE代理正在收集候选人
完成 ICE代理已完成聚会.
RTCPeerConnection.localDescription(只读) : 返回描述本地会话的RTCSessionDescription.如果尚未设置,则它可以为null.
RTCPeerConnection.peerIdentity(只读) : 返回RTCIdentityAssertion.它由一个idp(域名)和一个代表远程对等体身份的名称组成.
RTCPeerConnection.remoteDescription(只读) : 返回描述远程会话的RTCSessionDescription.如果尚未设置,则它可以为null.
RTCPeerConnection.signalingState(只读) : 返回描述本地连接的信令状态的RTCSignalingState枚举.此状态描述了SDP提供.此值更改时会触发signalingstatechange事件.可能的值 :
稳定 : 初始状态.正在进行SDP优惠/回答交换.
have-local-offer : 连接的本地端已在本地应用SDP优惠.
have-remote-offer : 连接的远程端已在本地应用了SDP优惠.
have-local-pranswer : 已经应用了远程SDP优惠,并在当地应用了SDP pranswer.
have-remote-pranswer : 已应用本地SDP,并远程应用SDP pranswer.
已关闭 : 连接已关闭.
事件处理程序
S.No. | 事件处理程序&说明 |
---|---|
1 | RTCPeerConnection.onaddstream 触发addstream事件时会调用此处理程序.当远程对等方将MediaStream添加到此连接时,将发送此事件. |
2 | RTCPeerConnection.ondatachannel 触发datachannel事件时会调用此处理程序.将RTCDataChannel添加到此连接时会发送此事件. |
3 | RTCPeerConnection.onicecandidate 在触发icecandidate事件时调用此处理程序.将RTCIceCandidate对象添加到脚本时发送此事件. |
4 | RTCPeerConnection.oniceconnectionstatechange 在触发iceconnectionstatechange事件时调用此处理程序.当iceConnectionState的值发生变化时,将发送此事件. |
5 | RTCPeerConnection.onidentityresult 触发identityresult事件时会调用此处理程序.在创建商品或通过getIdentityAssertion()的回答期间生成标识声明时发送此事件. |
6 | RTCPeerConnection.onidpassertionerror 当idpassertionerror事件发生时,将调用此处理程序被解雇.当IdP(Identitry Provider)在生成标识声明时发现错误时发送此事件. |
7 | RTCPeerConnection.onidpvalidation 触发idpvalidationerror事件时会调用此处理程序.当IdP(Identitry Provider)在验证身份声明时发现错误时发送此事件. |
8 | RTCPeerConnection.onnegotiationneeded 触发negotiationneeded事件时调用此处理程序.此事件由浏览器发送,以告知将来某个时候需要协商. |
9 | RTCPeerConnection.onpeeridentity 触发peeridentity事件时会调用此处理程序.在此连接上设置并验证对等身份后发送此事件. |
10 | RTCPeerConnection.onremovestream 触发signalingstatechange事件时会调用此处理程序.如果signalingState的值发生变化,则会发送此事件. |
11 | RTCPeerConnection.onsignalingstatechange 触发removestream事件时会调用此处理程序.从此连接中删除MediaStream时会发送此事件. |
方法
S.No. | Methods&说明 |
---|---|
1 | RTCPeerConnection() 返回一个新的RTCPeerConnection对象. |
2 | RTCPeerConnection.createOffer() 创建要约(请求)以查找远程对等方.此方法的两个第一个参数是成功和错误回调.可选的第三个参数是选项,如启用音频或视频流. |
3 | RTCPeerConnection.createAnswer() 在提供/应答协商过程中创建远程对等方收到的要约的答案.此方法的两个第一个参数是成功和错误回调.可选的第三个参数是要创建的答案的选项. |
4 | RTCPeerConnection.setLocalDescription() 更改本地连接描述.该描述定义了连接的属性.连接必须能够支持旧描述和新描述.该方法需要三个参数,RTCSessionDescription对象,如果描述更改成功则回调,如果描述更改失败则回调. |
5 | RTCPeerConnection.setRemoteDescription() 更改远程连接描述.该描述定义了连接的属性.连接必须能够支持旧描述和新描述.该方法需要三个参数,RTCSessionDescription对象,如果描述更改成功则回调,如果描述更改失败则回调. |
6 | RTCPeerConnection.updateIce() 更新ICE代理ping过程远程候选人和当地候选人. |
7 | RTCPeerConnection.addIceCandidate() 为ICE代理提供远程候选. |
8 | RTCPeerConnection.getConfiguration() 返回RTCConfiguration对象.它表示RTCPeerConnection对象的配置. |
9 | RTCPeerConnection.getLocalStreams() 返回本地MediaStream连接的数组. |
10 | RTCPeerConnection.getRemoteStreams() 返回一个远程MediaStream连接数组. |
11 | RTCPeerConnection.getStreamById() 按给定ID返回本地或远程MediaStream. |
12 | RTCPeerConnection.addStream() 将MediaStream添加为本地视频或音频源. |
13 | RTCPeerConnection.removeStream() 将MediaStream移除为本地视频或音频源. |
14 | RTCPeerConnection.close () Clo建立连接. |
15 | RTCPeerConnection.createDataChannel() 创建一个新的RTCDataChannel. |
16 | RTCPeerConnection.createDTMFSender() 创建一个新的RTCDTMFSender,与特定MediaStreamTrack关联.允许通过连接发送DTMF(双音多频)电话信号. |
17 | RTCPeerConnection.getStats() 创建一个新的RTCStatsReport,其中包含有关连接的统计信息. |
18 | RTCPeerConnection.setIdentityProvider() 设置IdP.采用三个参数 - 名称,用于通信的协议和可选的用户名. |
19 | RTCPeerConnection.getIdentityAssertion() 收集身份断言.预计不会在应用程序中处理此方法.所以你可以明确地称之为预期需要. |
建立连接
现在让我们创建一个示例应用程序.首先,通过"节点服务器"运行我们在"信令服务器"教程中创建的信令服务器.
页面上将有两个文本输入,一个用于登录,一个用于a我们想要连接的用户名.创建 index.html 文件并添加以下代码 :
您可以看到我们已经为登录添加了文本输入,登录按钮,其他对等用户名的文本输入以及连接 - 给他按钮.现在创建一个 client.js 文件并添加以下代码 :
var connection = new WebSocket('ws://localhost:9090'); var name = ""; var loginInput = document.querySelector('#loginInput'); var loginBtn = document.querySelector('#loginBtn'); var otherUsernameInput = document.querySelector('#otherUsernameInput'); var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn'); var connectedUser, myConnection; //when a user clicks the login button loginBtn.addEventListener("click", function(event){ name = loginInput.value; if(name.length > 0){ send({ type: "login", name: name }); } }); //handle messages from the server connection.onmessage = function (message) { console.log("Got message", message.data); var data = JSON.parse(message.data); switch(data.type) { case "login": onLogin(data.success); break; case "offer": onOffer(data.offer, data.name); break; case "answer": onAnswer(data.answer); break; case "candidate": onCandidate(data.candidate); break; default: break; } }; //when a user logs in function onLogin(success) { if (success === false) { alert("oops...try a different username"); } else { //creating our RTCPeerConnection object var configuration = { "iceServers": [{ "url": "stun:stun.1.google.com:19302" }] }; myConnection = new webkitRTCPeerConnection(configuration); console.log("RTCPeerConnection object was created"); console.log(myConnection); //setup ice handling //when the browser finds an ice candidate we send it to another peer myConnection.onicecandidate = function (event) { if (event.candidate) { send({ type: "candidate", candidate: event.candidate }); } }; } }; connection.onopen = function () { console.log("Connected"); }; connection.onerror = function (err) { console.log("Got error", err); }; // Alias for sending messages in JSON format function send(message) { if (connectedUser) { message.name = connectedUser; } connection.send(JSON.stringify(message)); };
您可以看到我们建立了与信令服务器的套接字连接.当用户单击登录按钮时,应用程序将其用户名发送到服务器.如果登录成功,应用程序将创建RTCPeerConnection对象并设置onicecandidate处理程序,该处理程序将所有找到的icecandidates发送给另一个对等方.现在打开页面并尝试登录.您应该看到以下控制台输出 :
下一步是为其他对等方创建要约.将以下代码添加到 client.js 文件 :
//setup a peer connection with another user connectToOtherUsernameBtn.addEventListener("click", function () { var otherUsername = otherUsernameInput.value; connectedUser = otherUsername; if (otherUsername.length > 0) { //make an offer myConnection.createOffer(function (offer) { console.log(); send({ type: "offer", offer: offer }); myConnection.setLocalDescription(offer); }, function (error) { alert("An error has occurred."); }); } }); //when somebody wants to call us function onOffer(offer, name) { connectedUser = name; myConnection.setRemoteDescription(new RTCSessionDescription(offer)); myConnection.createAnswer(function (answer) { myConnection.setLocalDescription(answer); send({ type: "answer", answer: answer }); }, function (error) { alert("oops...error"); }); } //when another user answers to our offer function onAnswer(answer) { myConnection.setRemoteDescription(new RTCSessionDescription(answer)); } //when we got ice candidate from another user function onCandidate(candidate) { myConnection.addIceCandidate(new RTCIceCandidate(candidate)); }
您可以看到,当用户点击"建立连接"按钮时,应用程序会向另一个对等方提供SDP优惠.我们还设置了 onAnswer 和 onCandidate 处理程序.重新加载您的页面,在两个选项卡中打开它,使用两个用户登录并尝试在它们之间建立连接.您应该看到以下控制台输出 :
现在建立对等连接.在下一个教程中,我们将添加视频和音频流以及文本聊天支持.