首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >信号的RTCDataChannel?

信号的RTCDataChannel?
EN

Stack Overflow用户
提问于 2015-05-03 16:53:35
回答 1查看 564关注 0票数 6

我一直在阅读这篇文章的信号解决方案。在建立连接时,作者提到了使用RTCDataChannel进行信令。

使用RTCDataChannel实现信令 启动WebRTC会话需要信令服务。 但是,一旦在两个对等点之间建立了连接,理论上RTCDataChannel就可以作为信令通道接管。这可能会减少信令延迟--因为消息直接发送--并有助于降低信令服务器带宽和处理成本。我们没有演示,但是看这个空间!

既然已经建立了连接,为什么需要信令呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-04 04:59:09

每一方最初声明它要发送的音频和/或视频轨道,这样就可以打开正确的端口数,并且可以确定对两个对等点都适用的分辨率和格式。需要一个信令通道来向对方发送SDP报价/应答,以及每个端口的ICE候选点。

一旦连接完毕,如果您不使用此设置--基本上永远不要向连接添加轨道、删除任何或显著更改磁道属性--那么您将不再需要信令服务器。

然而,如果你确实改变了其中的任何一件事,那么就需要重新协商,这正是它听起来的样子:信号通道上的另一轮就像第一轮一样。

添加音轨的理由可能是另一个摄像头,另一个视频源(可能来自另一个参与者),或者是屏幕共享之类的东西。

文章正确地指出,可以使用数据通道。这是演示!(目前只能使用Firefox。)

如果您有另一种发现方法,那么需要一个信令服务是错误的,这个演示很难证明这一点。

最初的连接是只聊天的,但任何一方都可以推动添加视频到混合。这方面的重新协商是在数据通道上完成的(因为没有信令服务器!)

使用小提琴的说明:

  1. 没有服务器(因为它是小提琴),所以按Offer按钮并复制报价。
  2. 将报价粘贴到同一地点,用同一把小提琴,在另一个标签上或在另一台机器上。
  3. 按回车,然后复制你得到的答案,并粘贴回第一小提琴。
  4. 再次按ENTER (还没有addTrack!)
  5. 您现在连接了两个数据通道:一个用于聊天,另一个用于信令。
  6. 现在,按addTrack在两端和视频应该显示在另一端。
  7. 按下addTrack在另一个方向,你应该有两个方向的视频。

代码语言:javascript
运行
复制
var dc = null, sc = null, pc = new mozRTCPeerConnection(), live = false;
pc.onaddstream = e => v2.mozSrcObject = e.stream;
pc.ondatachannel = e => dc? scInit(sc = e.channel) : dcInit(dc = e.channel);
v2.onloadedmetadata = e => { log("Face time!"); };

function addTrack() {
  navigator.mediaDevices.getUserMedia({video:true, audio:true})
  .then(stream => pc.addStream(v1.mozSrcObject = stream));
}

pc.onnegotiationneeded = e => {
  pc.createOffer().then(d => pc.setLocalDescription(d)).then(() => {
    if (live) sc.send(JSON.stringify({ "sdp": pc.localDescription }));
  }).catch(failed);
};

function scInit() {
  sc.onmessage = e => {
    var msg = JSON.parse(e.data);
    if (msg.sdp) {
      var desc = new mozRTCSessionDescription(JSON.parse(e.data).sdp);
      if (desc.type == "offer") {
        pc.setRemoteDescription(desc).then(() => pc.createAnswer())
        .then(answer => pc.setLocalDescription(answer)).then(() => {
          sc.send(JSON.stringify({ "sdp": pc.localDescription }));
        }).catch(failed);
      } else {
        pc.setRemoteDescription(desc).catch(failed);
      }
    } else if (msg.candidate) {
      pc.addIceCandidate(new mozRTCIceCandidate(msg.candidate)).catch(failed);
    }
  };
}

function dcInit() {
  dc.onopen = () => { live = true; log("Chat!"); };
  dc.onmessage = e => log(e.data);
}

function createOffer() {
  button.disabled = true;
  dcInit(dc = pc.createDataChannel("chat"));
  scInit(sc = pc.createDataChannel("signaling"));
  pc.createOffer().then(d => pc.setLocalDescription(d)).catch(failed);
  pc.onicecandidate = e => {
    if (e.candidate) return;
    if (!live) {
      offer.value = pc.localDescription.sdp;
      offer.select();
      answer.placeholder = "Paste answer here";
    } else {
      sc.send(JSON.stringify({ "candidate": e.candidate }));
    }
  };
};

offer.onkeypress = e => {
  if (e.keyCode != 13 || pc.signalingState != "stable") return;
  button.disabled = offer.disabled = true;
  var obj = { type:"offer", sdp:offer.value };
  pc.setRemoteDescription(new mozRTCSessionDescription(obj))
  .then(() => pc.createAnswer()).then(d => pc.setLocalDescription(d))
  .catch(failed);
  pc.onicecandidate = e => {
    if (e.candidate) return;
    if (!live) {
      answer.focus();
      answer.value = pc.localDescription.sdp;
      answer.select();
    } else {
      sc.send(JSON.stringify({ "candidate": e.candidate }));
    }
  };
};

answer.onkeypress = e => {
  if (e.keyCode != 13 || pc.signalingState != "have-local-offer") return;
  answer.disabled = true;
  var obj = { type:"answer", sdp:answer.value };
  pc.setRemoteDescription(new mozRTCSessionDescription(obj)).catch(failed);
};

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

var log = msg => div.innerHTML += "<p>" + msg + "</p>";
var failed = e => log(e.name + ": " + e.message + " line " + e.lineNumber);
代码语言:javascript
运行
复制
<video id="v1" height="120" width="160" autoplay muted></video>
<video id="v2" height="120" width="160" autoplay></video><br>
<button id="button" onclick="createOffer()">Offer:</button>
<textarea id="offer" placeholder="Paste offer here"></textarea><br>
Answer: <textarea id="answer"></textarea><br>
<button id="button" onclick="addTrack()">AddTrack</button>
<div id="div"></div><br>
Chat: <input id="chat"></input><br>

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30016613

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档