Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RTCDataChannel's ReadyState is not 'open'

I'm trying to send text over an RTCPeerConnection with RTCDataChannel using WebRTC's adapter.js, but I'm getting the following error:

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

My code is available via this fiddle and below:

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");

Am I doing anything wrong?

like image 391
mhenry Avatar asked Mar 18 '14 04:03

mhenry


2 Answers

I wrote the following code this morning that uses RTCPeerConnection and RTCDataChannel in a single page. The order in which these functions are declared is important.

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);
  });
});
like image 128
mhenry Avatar answered Oct 02 '22 09:10

mhenry


You can't just create peerConnection, dataChannel and start using it right away. And btw you don't have 2 peers here...

  1. You'll need to create peerConnections object in the 2 peers
  2. Transfer SDP's
  3. get ice candidates
  4. and only after that the dataChannel is open and then you can send information on top of it

I suggest start by reading this, it will give you knowledge of the basic concepts And then continue to this awesome code lab by Sam Dutton.

Update to answer mhenry's request: Here's the entirety of setting up data channel in one class: https://gist.github.com/shacharz/9661930 Follow the comments, you'll just need to:

  1. Add signaling, sending SDP's ice candidates to the other peer (targetId)
  2. If you'de like to handle all the connection lost and stuff like that by a higher level logic.
  3. Make sure that when receiving an sdp you call the "Handlmessage" method
  4. Use the class with its public methods: SetupCall, Send, Close
like image 24
shacharz Avatar answered Oct 02 '22 08:10

shacharz