具有手动信令的 WebRTC 数据通道的完整示例

问题描述 投票:0回答:2

我真的很难获得一个完整的 WebRTC 数据通道示例,我可以复制/粘贴它并且它可以工作。

我想要一个带有手动信令的 WebRTC 数据通道的 JavaScript 示例,即,当示例加载时,它会在一个文本框中提供信令数据。

我手动复制数据(突出显示、复制)并将其粘贴到对等方的窗口中,该窗口有一个文本框来接受该信令数据。我相信信令数据中需要有一个“答案”,因此也需要有相应的文本框等待该输入。

该示例可以使用 Google 的免费 STUN 服务器吗?

我对一点一滴的例子感到非常困惑。我想要一个包含 HTML 和 JavaScript 的文件(请不要包含 CSS 或 jQuery)。代码仅在 Chrome 上运行就足够了。

javascript webrtc channel rtcdatachannel signaling
2个回答
26
投票

就是这里。单击两个不同选项卡/窗口/浏览器/机器中的蓝色按钮:

const output = document.getElementById('output');
const config = {
  iceServers: [{
    urls: "stun:stun.l.google.com:19302" // list of free STUN servers: https://gist.github.com/zziuni/3741933
  }]
};
const pc = new RTCPeerConnection(config);
const dc = pc.createDataChannel("chat", {
  negotiated: true,
  id: 0
});
const log = msg => output.innerHTML += `<br>${msg}`;
dc.onopen = () => chat.select();
dc.onmessage = e => log(`> ${e.data}`);
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState);

chat.onkeypress = function(e) {
  if (e.keyCode != 13) return;
  dc.send(chat.value);
  log(chat.value);
  chat.value = "";
};

async function createOffer() {
  button.disabled = true;
  await pc.setLocalDescription(await pc.createOffer());
  pc.onicecandidate = ({
    candidate
  }) => {
    if (candidate) return;
    offer.value = pc.localDescription.sdp;
    offer.select();
    answer.placeholder = "Paste answer here. And Press Enter";
  };
}

offer.onkeypress = async function(e) {
  if (e.keyCode != 13 || pc.signalingState != "stable") return;
  button.disabled = offer.disabled = true;
  await pc.setRemoteDescription({
    type: "offer",
    sdp: offer.value
  });
  await pc.setLocalDescription(await pc.createAnswer());
  pc.onicecandidate = ({
    candidate
  }) => {
    if (candidate) return;
    answer.focus();
    answer.value = pc.localDescription.sdp;
    answer.select();
  };
};

answer.onkeypress = function(e) {
  if (e.keyCode != 13 || pc.signalingState != "have-local-offer") return;
  answer.disabled = true;
  pc.setRemoteDescription({
    type: "answer",
    sdp: answer.value
  });
};

pc.onconnectionstatechange = ev => handleChange();
pc.oniceconnectionstatechange = ev => handleChange();

function handleChange() {
  let stat = 'ConnectionState: <strong>' + pc.connectionState + '</strong> IceConnectionState: <strong>' + pc.iceConnectionState + '</strong>';
  document.getElementById('stat').innerHTML = stat;
  console.log('%c' + new Date().toISOString() + ': ConnectionState: %c' + pc.connectionState + ' %cIceConnectionState: %c' + pc.iceConnectionState,
    'color:yellow', 'color:orange', 'color:yellow', 'color:orange');
}
handleChange();
<p id=stat></p>
<button id="button" onclick="createOffer()">Offer:</button>
<textarea id="offer" placeholder="Paste offer here. And press Enter"></textarea> Answer: <textarea id="answer"></textarea><br> Chat: <input id="chat"><br>
<pre id="output">Chat: </pre>

然后按照以下步骤操作:

  1. 在窗口 A 中,按
    Offer
    按钮并将报价复制到 剪贴板。
  2. 在窗口 B 中,将该报价粘贴到“在此处粘贴报价”,然后按 Enter 键。
  3. 复制几秒钟后出现的答案。
  4. 返回窗口 A 并将答案粘贴到显示“在此处粘贴答案”的位置,然后按 Enter

您现在应该会看到一条消息,表明您已“已连接”。在聊天框中输入内容即可聊天!

如果您和朋友以某种方式交换提议/答案,那么您现在就拥有了直接的点对点连接。这应该适用于世界各地(模对称NAT路由器);不涉及数据服务器。


0
投票

是否可以对其进行调整以用于更多两个选项卡/Windows???

© www.soinside.com 2019 - 2024. All rights reserved.