Hongbo Miao
Hongbo Miao

Reputation: 50016

Cannot get message through data channel

I am using WebRTC. My audio and video are working well. I try to add a data channel.

I use openDataChannel() function just after ice handling setup and before creating offer.

// setup ice handling
this.myConnection.onicecandidate = (ev) => {
    if (ev.candidate) {
        this.send({
            type: 'candidate',
            candidate: ev.candidate
        });
    }
};
this.openDataChannel();

// openDataChannel()

openDataChannel() {
    let dataChannelOptions = {
        reliable: true
    };
    this.dataChannel = this.myConnection.createDataChannel('myLabel', dataChannelOptions);

    this.dataChannel.onerror = (err) => {
        console.log(err);
    };

    this.dataChannel.onmessage = (ev) => {
        console.log('Got message ', ev.data);
    };

    this.dataChannel.onopen = () => {
        console.log('Data Channel is opened.');
        console.log('this.dataChannel', this.dataChannel);   // Screenshot below
        console.log('this.myConnection', this.myConnection); // Screenshot below
        this.dataChannel.send('Hello!');
    };

    this.dataChannel.onclose = () => {
        console.log('Data Channel is closed.');
    };
}

In latest Chrome and Opera, the data channel can open and close correctly. But the other user cannot get message. And no error shows up.

In Firefox, it is weird, the data channel open correctly, but after 7 or 8 seconds, the data channel close automatically (Audio and video are still working).

What can cause this? Thanks

Below is this.dataChannel and this.myConnection:

enter image description here

Upvotes: 1

Views: 1862

Answers (1)

mido
mido

Reputation: 25064

I guess the mistake you are making is creating datachannel in both ends and not accepting either on the other end through ondatachannel, and you end up with two dangling datachannels that send message but no one is listening on the other side. Take a look at the example below, works in chrome and firefox:

"use strict";
let pc1 = new RTCPeerConnection()
  , pc2 = new RTCPeerConnection()
  , div = document.getElementById('log')
  , add = (pc, can) => can && pc.addIceCandidate(can).catch(log)
  , log = msg => div.innerHTML += "<br>" + msg
  , exchangeSDP = () => pc1.createOffer().then(d => pc1.setLocalDescription(d))
      .then(() => pc2.setRemoteDescription(pc1.localDescription))
      .then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
      .then(() => pc1.setRemoteDescription(pc2.localDescription))
      .catch(log)
  , setChannelEvents = (dataChannel, label) => {
          dataChannel.onerror = log;
          dataChannel.onclose = () => log(`Data Channel is closed: ${label}`);
          dataChannel.onmessage = ev => log(`${label}, Got message:  ${ev.data}`);
          dataChannel.onopen = () => log(`Data Channel is opened: ${label}`);          
          setTimeout(() => dataChannel.send('Hello from '+label), 3000);
      }
  
pc1.onicecandidate = e => add(pc2, e.candidate);
pc2.onicecandidate = e => add(pc1, e.candidate);
pc1.oniceconnectionstatechange = e => log(pc1.iceConnectionState);
setChannelEvents( pc1.createDataChannel('label', { reliable: true }), 'Peer1');
pc2.ondatachannel = evt => setChannelEvents(evt.channel, 'Peer2');
exchangeSDP();
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<div id='log'></div>

P.S: code in fiddle, code taken from jib's answer and modified.

Upvotes: 3

Related Questions