带有手动信令的 WebRTC 数据通道,请举例?

Posted

技术标签:

【中文标题】带有手动信令的 WebRTC 数据通道,请举例?【英文标题】:WebRTC datachannel with manual signaling, example please? 【发布时间】:2019-07-25 14:54:43 【问题描述】:

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

我想要一个带有手动信令的 WebRTC 数据通道的 javascript 示例,即当示例加载时,它会在一个文本框中提供信令数据。我手动复制数据(突出显示、复制)并将其粘贴到对等的窗口中,该窗口有一个文本框来接受该信令数据。我相信信令数据中需要有一个“答案”,因此也需要有相应的文本框等待该输入。谢谢你。

该示例能否使用 Google 的免费 STUN 服务器。

我对一点一点的例子感到非常困惑,我想要一个包含 html 和 Javascript 的文件(请不要使用 CSS 或 JQuery)。代码仅在 Chrome 上运行就足够了。谢谢。

【问题讨论】:

我认为这个关于数据通道 API 如何工作的基本问题值得一个简单的答案。 【参考方案1】:

来了。点击下方two不同标签/窗口/浏览器/机器中的蓝色按钮:

const output = document.getElementById('output');
const config = 
  iceServers: [
    urls: "stun:stun.1.google.com:19302"
  ]
;
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>

然后按照以下步骤操作:

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

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

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

【讨论】:

非常感谢您的回复。我不太清楚如何使用它。您能否给我一个分步指南,即 1)按窗口 1 上的报价按钮。2)从窗口 1 的报价文本框中复制文本并将其粘贴到窗口 2 的报价文本框中......非常感谢。 好的,让我细化步骤 非常感谢!有效!你的答案很好,甚至是如何使用它的步骤。我敢肯定,如果不是你、*** 和互联网,我会花很多钱来完成这项工作。太棒了! 这似乎适用于我的 Firefox 69.0.1,但不适用于 Chrome 版本 78.0.3904.97(官方构建)(64 位)。任何想法为什么? @Cameron 刚刚测试过它,在 Chrome 中仍然适用于我!您是在同一台机器或 LAN 上进行测试,还是在不同网络之间进行测试?你来回剪切粘贴需要多长时间?也许 Chrome 会在几秒钟后超时?

以上是关于带有手动信令的 WebRTC 数据通道,请举例?的主要内容,如果未能解决你的问题,请参考以下文章

WebRTC 有多少个通道以及使用了哪些传输?

Webrtc 数据通道可以用于 Lync 和非 lync 用户之间的文件传输吗?

webrtc博客收藏

【速成】WebRTC 交互流程

RTCDataChannel 用于信令?

WebRTC介绍及简单应用