RTCPeerConnection API是每个浏览器之间对等连接的核心。要创建RTCPeerConnection对象,只需编写:
var pc = RTCPeerConnection(config);
其中config参数至少包含密钥iceServers。它是一个URL对象数组,包含有关STUN和TURN服务器的信息,用于查找ICE候选对象。您可以在code.google.com上找到可用的公共STUN服务器列表。
根据您是调用方还是被调用方,RTCPeerConnection对象在连接的两边使用的方式略有不同。
这是用户流程的示例:
下面给出的是RTCPeerConnection的常用事件处理程序。
序号 | 事件处理程序和描述 |
---|---|
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.onidpassertion错误触发idpassertionerror事件时,将调用此处理程序。当IdP(身份提供程序)在生成身份声明时发现错误时,将发送此事件。 |
7 | RTCPeerConnection.onidpvalidation触发idpvalidationerror事件时,将调用此处理程序。当IdP(身份提供程序)在验证身份声明时发现错误时,将发送此事件。 |
8 | 需要RTCPeerConnection.onnegotiation触发needingneeded事件时,将调用此处理程序。此事件由浏览器发送,以通知将来需要进行协商。 |
9 | RTCPeerConnection.onpeeridentity触发peeridentity事件时,将调用此处理程序。在此连接上设置并验证对等身份后,将发送此事件。 |
10 | RTCPeerConnection.onremovestream触发signalingstatechange事件时,将调用此处理程序。当signalingState的值更改时,将发送此事件。 |
11 | RTCPeerConnection.onsignalingstatechange触发removestream事件时,将调用此处理程序。从此连接中删除MediaStream时,将发送此事件。 |
下面给出的是RTCPeerConnection的常用方法。
序号 | 方法与说明 |
---|---|
1个 | RTCPeerConnection()返回一个新的RTCPeerConnection对象。 |
2 | RTCPeerConnection.createOffer()创建要约(请求)以查找远程对等方。此方法的前两个参数是成功和错误回调。可选的第三个参数是选项,例如启用音频或视频流。 |
3 | RTCPeerConnection.createAnswer()在报价/答案协商过程中为远程对等方收到的报价创建答案。此方法的前两个参数是成功和错误回调。可选的第三个参数是要创建的答案的选项。 |
4 | RTCPeerConnection.setLocalDescription()更改本地连接描述。该描述定义了连接的属性。该连接必须能够支持新旧描述。该方法具有三个参数:RTCSessionDescription对象,描述更改成功的回调,描述更改失败的回调。 |
5 | RTCPeerConnection.setRemoteDescription()更改远程连接描述。该描述定义了连接的属性。该连接必须能够支持新旧描述。该方法采用三个参数:RTCSessionDescription对象,描述更改成功的回调,描述更改失败的回调。 |
6 | RTCPeerConnection.updateIce()更新ping远程候选者并收集本地候选者的ICE代理程序。 |
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()关闭连接。 |
15 | RTCPeerConnection.createDataChannel()创建一个新的RTCDataChannel。 |
16 | RTCPeerConnection.createDTMFSender()创建一个与特定MediaStreamTrack关联的新RTCDTMFSender。允许通过连接发送DTMF(双音多频)电话信令。 |
17 | RTCPeerConnection.getStats()创建一个新的RTCStatsReport,其中包含有关连接的统计信息。 |
18岁 | RTCPeerConnection.setIdentityProvider()设置IdP。具有三个参数-名称,用于通信的协议和可选的用户名。 |
19 | RTCPeerConnection.getIdentityAssertion()收集身份声明。不应在应用程序中处理此方法。因此,您可以明确地将其称为仅预期需求。 |
现在让我们创建一个示例应用程序。首先,通过“节点服务器”运行我们在“信令服务器”教程中创建的信令服务器。
页面上将有两个文本输入,一个用于登录,另一个用于我们要连接的用户名。创建一个index.html文件并添加以下代码:
<html lang = "en"> <head> <meta charset = "utf-8" /> </head> <body> <div> <input type = "text" id = "loginInput" /> <button id = "loginBtn">Login</button> </div> <div> <input type = "text" id = "otherUsernameInput" /> <button id = "connectToOtherUsernameBtn">Establish connection</button> </div> <script src = "client2.js"></script> </body> </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处理程序。重新加载页面,在两个选项卡中打开它,使用两个用户登录并尝试在他们之间建立连接。您应该看到以下控制台输出:
现在,对等连接已建立。在接下来的教程中,我们将添加视频和音频流以及文本聊天支持。