【问题标题】:RTCDataChannel's ReadyState is not 'open'RTCDataChannel 的 ReadyState 未“打开”
【发布时间】:2014-03-20 20:34:48
【问题描述】:

我正在尝试使用WebRTC's adapter.js 通过RTCPeerConnectionRTCDataChannel 发送文本,但出现以下错误:

Uncaught InvalidStateError:
Failed to execute 'send' on 'RTCDataChannel':
RTCDataChannel.readyState is not 'open'

我的代码可通过this fiddle 及以下获得:

var peerConnection = new RTCPeerConnection(null, {
  optional: [{
    RtpDataChannels: true
  }]
});

peerConnection.ondatachannel = function(event) {
  receiveChannel = event.channel;
  receiveChannel.onmessage = function(event){
    alert(event.data);
  };
};

var dataChannel = peerConnection.createDataChannel("data", {reliable: false});
dataChannel.send("Hello");

我做错了什么吗?

【问题讨论】:

  • 看来您以前从未使用过 RTC。下面提到的网站是不错的起点,但我建议您阅读this。它会引导您建立 RTC 连接。
  • Offtopic:不推荐使用 rtp 数据通道。你应该使用 sctp 的。 here你可以找到更多信息

标签: javascript webrtc


【解决方案1】:

我今天早上编写了以下代码,它在一个页面中使用了RTCPeerConnectionRTCDataChannel。这些函数的声明顺序很重要。

var localPeerConnection, remotePeerConnection, sendChannel, receiveChannel;

localPeerConnection = new RTCPeerConnection(null, {
  optional: [{
    RtpDataChannels: true
  }]
});

localPeerConnection.onicecandidate = function(event) {
  if (event.candidate) {
    remotePeerConnection.addIceCandidate(event.candidate);
  }
};

sendChannel = localPeerConnection.createDataChannel("CHANNEL_NAME", {
  reliable: false
});

sendChannel.onopen = function(event) {
  var readyState = sendChannel.readyState;
  if (readyState == "open") {
    sendChannel.send("Hello");
  }
};

remotePeerConnection = new RTCPeerConnection(null, {
  optional: [{
    RtpDataChannels: true
  }]
});

remotePeerConnection.onicecandidate = function(event) {
  if (event.candidate) {
    localPeerConnection.addIceCandidate(event.candidate);
  }
};

remotePeerConnection.ondatachannel = function(event) {
  receiveChannel = event.channel;
  receiveChannel.onmessage = function(event) {
    alert(event.data);
  };
};

localPeerConnection.createOffer(function(desc) {
  localPeerConnection.setLocalDescription(desc);
  remotePeerConnection.setRemoteDescription(desc);
  remotePeerConnection.createAnswer(function(desc) {
    remotePeerConnection.setLocalDescription(desc);
    localPeerConnection.setRemoteDescription(desc);
  });
});

【讨论】:

  • 这里可选的“RtpDataChannels”的目的是什么?
  • 我其实不知道。我包含它是因为我看到了其他使用它的示例;主要在official WebRTC site。它应该在没有可选参数的情况下默认为 true,但我不想通过假设可以在不同浏览器中以不同方式实现的默认值来冒某些不工作的风险。
  • 如果我们想在 Firefox 上使用 DataChannels API,则需要 RtpDataChannels。参考:developer.mozilla.org/en-US/docs/Web/Guide/API/WebRTC/…
  • RtpDataChannels 实际上是一个旧的 Chrome 东西,不应该再使用了。
  • 我认为这应该包含在官方文档或其他内容中。非常感谢...
【解决方案2】:

您不能只创建 peerConnection、dataChannel 并立即开始使用它。 顺便说一句,你这里没有 2 个同伴......

  1. 您需要在 2 个对等点中创建 peerConnections 对象
  2. 转移 SDP 的
  3. 获得冰候选人
  4. 只有在打开数据通道之后,您才能在其上发送信息

我建议先阅读this,它会让你了解基本概念 然后继续this Sam Dutton 的 awesome code lab。

更新以回答 mhenry 的请求: 这是在一个类中设置数据通道的全部内容:https://gist.github.com/shacharz/9661930 跟随 cmets,您只需要:

  1. 添加信令,将 SDP 的候选冰发送到其他对等点 (targetId)
  2. 如果您想通过更高级别的逻辑来处理所有丢失的连接以及类似的事情。
  3. 确保在收到 sdp 时调用“Handlmessage”方法
  4. 使用该类及其公共方法:SetupCall、Send、Close

【讨论】:

  • 我想我正在寻找的是在单个页面中使用 RTCPeerConnectionRTCDataChannel 的直接示例(将文本从一个区域复制到另一个区域,或者像我的示例代码推送文本到警报),而无需使用 RTCPeerConnection 进行视频或 JavaScript 代码来修改用户界面。我在网上看到的很多代码都是乱七八糟的,到处都是抄的,所以里面包含了代码不可达的函数。
  • 您想在单个页面中查看 2 个对等点的“简化”本地示例吗?或者您需要 2 个选项卡才能运行的示例,这也可以在 2 台远程计算机之间运行?
  • 后者最好。
  • 我也有一个例子,虽然代码很乱。它不使用文本框,而是使用四个字符的密钥和一个信令服务器。拿到钥匙后,您唯一需要做的就是与其他人分享。如果其他人输入该密钥,则服务器知道它应该在哪些计算机之间交换数据(通过 websockets,因为它们可以通过 2 种方式发送数据,您需要重新打开 xhr - 但这也是一种选择)。它不使用数据通道,而是使用音频和视频的流通道。不过,我仍在寻找带有数据通道的版本。
猜你喜欢
  • 1970-01-01
  • 2021-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多