2016-10-23 39 views
1

2つのピア間でWebRTCデータチャネルメッセージを受信できません。WebRTCデータチャネル接続が確立されていますが、メッセージが届かない

以下は両方のピアが同じページであり、シグナリングチャネルがプレーンJavaScriptオブジェクト交換で置き換えられているMVPです。

私はトリックルICEを選択して使用していません。私はそれを使用しないという欠点を認識していますが、私は下のMVPに干渉してはいけません。

コードは期待どおりに動作し、すべてのログメッセージが通過します。欠落しているのは、データチャネルのメッセージ処理用のメッセージだけです。メッセージがどちらのピアからも送られないかのようです。これは、テストを送信しようとするイベントハンドラです。 メソッド呼び出しが失敗し、nullの参照エラーが発生し、その根本原因を追跡できませんでした。

私はUntangling the WebRTC Flowに続き、私はこのMVPのどこにいるのですか。回答のYou can see it live here so you don't have to run it yourself.

class Peer { 
    constructor(name) { 
     this.name = name; 
    } 
    offer() { 
     const peerConnection = new webkitRTCPeerConnection({ iceServers: [ { url: "stun:stun.l.google.com:19302" } ] }); 
     peerConnection.onnegotiationneeded = event => console.debug(this.name, "onnegotiationneeded"); 
     peerConnection.onsignalingstatechange = event => console.debug(this.name, "onsignalingstatechange", peerConnection.signalingState); 
     peerConnection.onicegatheringstatechange = event => console.debug(this.name, "onicegatheringstatechange", peerConnection.iceGatheringState); 
     peerConnection.oniceconnectionstatechange = event => console.debug(this.name, "oniceconnectionstatechange", peerConnection.iceConnectionState); 
     peerConnection.onconnectionstatechange = event => console.debug(this.name, "onconnectionstatechange", peerConnection.connectionState); 
     peerConnection.ondatachannel = event => { 
     const dataChannel = event.channel; 
     dataChannel.onopen = event => { 
      console.debug(this.name, "onopen"); 
      dataChannel.send("TEST"); 
     }; 
     dataChannel.onclose = event => console.debug(this.name, "onclose"); 
     dataChannel.onerror = event => console.debug(this.name, "onerror"); 
     dataChannel.onmessage = event => console.debug(this.name, "onmessage"); 
     console.debug(this.name, "ondatachannelO"); 
     this.dataChannel = dataChannel; 
     }; 

     return new Promise((resolve, reject) => { 
     peerConnection.onicecandidate = event => { 
      if (!event.candidate) { 
      peerConnection.createOffer() 
       .then(offer => { 
       console.debug(this.name, "created an offer with candidates."); 
       this.peerConnection = peerConnection; 
       resolve(peerConnection.localDescription); 
       }) 
       .catch(reject); 
      } 
     }; 
     peerConnection.createDataChannel("datachannel"); 
     peerConnection.createOffer() 
      .then(offer => { 
      console.debug(this.name, "created an offer without candidates."); 
      peerConnection.setLocalDescription(offer) 
       .then(() => { 
       console.debug(this.name, "set local description. Collecting candidates…"); 
       }) 
       .catch(reject); 
      }) 
      .catch(reject); 
     }); 
    } 
    answer(offer) { 
     const peerConnection = new webkitRTCPeerConnection({ iceServers: [ { url: "stun:stun.l.google.com:19302" } ] }); 
     peerConnection.onnegotiationneeded = event => console.debug(this.name, "onnegotiationneeded"); 
     peerConnection.onsignalingstatechange = event => console.debug(this.name, "onsignalingstatechange", peerConnection.signalingState); 
     peerConnection.onicegatheringstatechange = event => console.debug(this.name, "onicegatheringstatechange", peerConnection.iceGatheringState); 
     peerConnection.oniceconnectionstatechange = event => console.debug(this.name, "oniceconnectionstatechange", peerConnection.iceConnectionState); 
     peerConnection.onconnectionstatechange = event => console.debug(this.name, "onconnectionstatechange", peerConnection.connectionState); 
     peerConnection.ondatachannel = event => { 
     const dataChannel = event.channel; 
     dataChannel.onopen = event => { 
      console.debug(this.name, "onopen"); 
      dataChannel.send("TEST"); 
     }; 
     dataChannel.onclose = event => console.debug(this.name, "onclose"); 
     dataChannel.onerror = event => console.debug(this.name, "onerror"); 
     dataChannel.onmessage = event => console.debug(this.name, "onmessage"); 
     console.debug(this.name, "ondatachannelA"); 
     this.dataChannel = dataChannel; 
     }; 
     return new Promise((resolve, reject) => { 
     peerConnection.onicecandidate = event => { 
      if (!event.candidate) { 
      peerConnection.createAnswer() 
       .then(answer => { 
       console.debug(this.name, "created an answer with candidates."); 
       resolve(peerConnection.localDescription); 
       }) 
       .catch(reject); 
      } 
     }; 
     peerConnection.setRemoteDescription(offer) 
      .then(() => { 
      console.debug(this.name, "set remote description."); 
      peerConnection.createAnswer() 
       .then(answer => { 
       console.debug(this.name, "created an answer without candidates."); 
       peerConnection.setLocalDescription(answer) 
        .then(() => { 
        console.debug(this.name, "set local description."); 
        }) 
        .catch(reject); 
       }) 
       .catch(reject); 
      }) 
      .catch(reject); 
     }); 
    } 
    sealTheDeal(proffer) { 
     return new Promise((resolve, reject) => { 
     this.peerConnection.setRemoteDescription(proffer) 
      .then(() => { 
      console.debug(this.name, "set remote description."); 
      resolve(); 
      }) 
      .catch(console.e); 
     }); 
    } 
    send() { 
     this.dataChannel.send("TEST"); 
    } 
    } 
    function flow() { 
    const peerA = new Peer("Alice"); 
    const peerB = new Peer("Bob"); 
    peerA.offer() 
     .then(offer => { 
     console.debug("Signal transfering offer from Alice to Bob."); 
     peerB.answer(offer) 
      .then(proffer => { 
      console.debug("Signal transfering proffer from Bob to Alice."); 
      peerA.sealTheDeal(proffer) 
       .then(() => { 
       peerB.offer() 
        .then(offer => { 
        console.debug("Signal transfering offer from Bob to Alice."); 
        peerA.answer(offer) 
         .then(proffer => { 
         console.debug("Signal transfering proffer from Alice to Bob."); 
         peerB.sealTheDeal(proffer) 
          .then(() => { 
          console.debug("HYPE"); 
          peerA.send("From Alice to Bob."); 
          peerB.send("From Bob to Alice."); 
          }) 
          .catch(console.error); 
         }) 
         .catch(console.error); 
        }) 
        .catch(console.error); 
       }) 
       .catch(console.error); 
      }) 
      .catch(console.error); 
     }) 
     .catch(console.error); 
     window.peerA = peerA; 
     window.peerB = peerB; 
    } 
    flow(); 

答えて

1

peerConnection.ondatachannelのみ発生します。

this.dataChannel = peerConnection.createDataChannel("datachannel"); 

その他のコメント:

  • webkitRTCPeerConnectionはChromeのみ/ Operaで動作します

    オファー側はこのようなデータチャネルを取得します。 polyfillまたはadapter.jsを使用する必要があります。

  • 約束では、運命のピラミッドは不要です。
  • promise constructor anti-patternは避けてください。

例:

var pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection(); 
 

 
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate); 
 
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate); 
 
pc1.oniceconnectionstatechange = e => console.log(pc1.iceConnectionState); 
 

 
pc1.onnegotiationneeded = e => 
 
    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(e => console.log(e)); 
 

 
var dc1, dc2; 
 
pc2.ondatachannel = e => { 
 
    dc2 = e.channel; 
 
    dc2.onopen =() => console.log("Chat!"); 
 
    dc2.onmessage = e => console.log("> " + e.data); 
 
}; 
 

 
dc1 = pc1.createDataChannel("chat"); 
 
dc1.onopen =() => (chat.disabled = false, chat.select()); 
 

 
chat.onkeypress = e => { 
 
    if (e.keyCode != 13) return; 
 
    dc1.send(chat.value); 
 
    chat.value = ""; 
 
};
Chat: <input id="chat" disabled></input> 
 
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

関連する問題