RTCDataChannel send method not sending data

|▌冷眼眸甩不掉的悲伤 提交于 2020-07-07 04:23:31

问题


I'm having a strange problem with RTCDataChannel.

I'm doing some research on WebRTC and I have working WebRTC audio/video chat already. Now I wanted to add text chat and file sharing to it using RTCDataChannel.

I've created RTCDataChannel like this:

var dataChannelOptions = {
    reliable: true,
    maxRetransmitTime: "2000"
};

dataChannel = yourConnection.createDataChannel("testDataChannel", dataChannelOptions);

dataChannel.onerror = function (error) {
    console.log("dataChannel.OnError:", error);
};

dataChannel.onmessage = function (event) {
    console.log("dataChannel.OnMessage:", event);
};

dataChannel.onopen = function (event) {
    console.log("dataChannel.OnOpen", event);
    dataChannel.send("Hello World!");
};

dataChannel.onclose = function (event) {
    console.log("dataChannel.OnClose", event);
};

And only thing that I receieve on both sides is log from first line of dataChannel.onopen. I don't receive log from dataChannel.onmessage.

No errors..

When I manually call dataChannel.send result is the same.

Tested on:
Google Chrome (50.0.2661.94)
Firefox (45.0.2)

Anyone can help with that?


回答1:


this is a common mistake people make, you are creating datachannel on both browsers, but not accepting on either, you need use the RTCPeerConnection's ondatachannel event and set the listeners




回答2:


I was facing the same issue. As per RTCDataChannel documentation, you should handle a callback on Peer Connection object to receive the data on data channel. Below code might be helpful :

Step 1 : Define Callback Handlers :

  var handleDataChannelOpen = function (event) {
    console.log("dataChannel.OnOpen", event);
    dataChannel.send("Hello World!");
  };

  var handleDataChannelMessageReceived = function (event) {
    console.log("dataChannel.OnMessage:", event);
  };

  var handleDataChannelError = function (error) {
    console.log("dataChannel.OnError:", error);
  };

  var handleDataChannelClose = function (event) {
    console.log("dataChannel.OnClose", event);
  };

  var handleChannelCallback = function (event) {
     dataChannel = event.channel;
     dataChannel.onopen = handleDataChannelOpen;
     dataChannel.onmessage = handleDataChannelMessageReceived;
     dataChannel.onerror = handleDataChannelError;
     dataChannel.onclose = handleDataChannelClose;
  };

Step 2 : Create RTC Peer Connection :

  var pc = new RTCPeerConnection();
  pc.ondatachannel = handleChannelCallback;

Step 3 : Create Data Channel :

  var dataChannel = pc.createDataChannel('dataChannelName', {});

  dataChannel.onopen = handleDataChannelOpen;
  dataChannel.onmessage = handleDataChannelMessageReceived;
  dataChannel.onerror = handleDataChannelError;
  dataChannel.onclose = handleDataChannelClose;

In your code you just need to add ondatachannel callback handler to receive the data.




回答3:


I think the biggest misconception, at least for me, is that each client needs to keep a reference to TWO channels (please correct me if wrong, because it doesn't feel right at all). One for sending, one for receiving. This is basically what @Nikhil's answer is showing. He creates named functions for the handlers, in order to use them twice.

Also note that you can define the data connection right after peerConnection instantiation. I've read conflicting things saying you have to do it from only the caller, or only after the connection is ready. Maybe that was true of older versions of WebRTC but this works in current chrome (whatever is out as of oct 2017).

let pc = new RTCPeerConnection({"iceServers": [{"url": "stun:stun.l.google.com:19302"}]});

const handleDataChannelOpen = (event) =>{
    console.log("dataChannel.OnOpen", event);
    sendChannel.send("Hello World!");
};

const handleDataChannelMessageReceived = (event) =>{
    console.log("dataChannel.OnMessage:", event);
};

const handleDataChannelError = (error) =>{
    console.log("dataChannel.OnError:", error);
};

const handleDataChannelClose = (event) =>{
    console.log("dataChannel.OnClose", event);
};


let sendChannel = pc.createDataChannel('text', {});
sendChannel.onopen = handleDataChannelOpen;
sendChannel.onmessage = handleDataChannelMessageReceived;
sendChannel.onerror = handleDataChannelError;
sendChannel.onclose = handleDataChannelClose;


pc.ondatachannel = (event) =>{
    console.log("on data channel")
    let receiveChannel = event.channel;
    receiveChannel.onopen = handleDataChannelOpen;
    receiveChannel.onmessage = handleDataChannelMessageReceived;
    receiveChannel.onerror = handleDataChannelError;
    receiveChannel.onclose = handleDataChannelClose;

    let button = document.getElementById(this.id + "-submit");
    button.onclick = () =>{
        receiveChannel.send("hello from " + this.id)
    };
};

//... do your connection with servers



回答4:


This is working Client Side Code, I am sharing here, may be it helped somebody. Please do appreciate if it helped you:

            var connection = new WebSocket('wss://127.0.0.1:3000'); 
            var name = "";

            var loginInput = document.querySelector('#loginInput'); 
            var loginBtn = document.querySelector('#loginBtn'); 

            var otherUsernameInput = document.querySelector('#otherUsernameInput'); 
            var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn'); 
            var msgInput = document.querySelector('#msgInput'); 
            var sendMsgBtn = document.querySelector('#sendMsgBtn'); 
            var connectedUser, myConnection, dataChannel;

            //when a user clicks the login button 
            loginBtn.addEventListener("click", function(event) { 
               name = loginInput.value; 

               if(name.length > 0) { 
                  send({ 
                     type: "login", 
                     name: name 
                  }); 
               } 
            });

            //handle messages from the server 
            connection.onmessage = function (message) {
            //    if(message)
                var data = JSON.parse(message.data);
                console.log("Got message", data.type);
               switch(data.type) { 
                  case "login": 
                     onLogin(data.success); 
                     break; 
                  case "offer": 
                     onOffer(data.offer, data.name); 
                     break; 
                  case "answer":
                     onAnswer(data.answer); 
                     break; 
                  case "candidate": 
                     onCandidate(data.candidate); 
                     break; 
                  default: 
                     break; 
               } 
            }; 

            //when a user logs in 
            function onLogin(success) { 

               if (success === false) { 
                  alert("oops...try a different username"); 
               } else { 
                  //creating our RTCPeerConnection object 
                  var configuration = { 
                     "iceServers": [{ "url": "stun:stun.1.google.com:19302" }] 
                  }; 

                  myConnection = new RTCPeerConnection(configuration); 

                  console.log("RTCPeerConnection object was created"); 
                  console.log(myConnection); 

                  //setup ice handling 
                  //when the browser finds an ice candidate we send it to another peer 
                  myConnection.onicecandidate = function (event) { 

                     if (event.candidate) { 
                        send({ 
                           type: "candidate", 
                           candidate: event.candidate 
                        });
                     } 
                  }; 
                  myConnection.ondatachannel = function (event) {
                      var receiveChannel = event.channel;
                      receiveChannel.onmessage = function (event) {
                          console.log("ondatachannel message:", event.data);
                      };
                  }; 

                  openDataChannel();
                  console.log("DataChannel Opened..");

               } 
            };

            connection.onopen = function () { 
               console.log("Connected"); 
            }; 

            connection.onerror = function (err) { 
               console.log("Got error", err); 
            };

            // Alias for sending messages in JSON format 
            function send(message) { 
               if (connectedUser) { 
                  message.name = connectedUser; 
               }

               connection.send(JSON.stringify(message)); 
            };

            //setup a peer connection with another user 
            connectToOtherUsernameBtn.addEventListener("click", function () {

               var otherUsername = otherUsernameInput.value;
               connectedUser = otherUsername;

               if (otherUsername.length > 0) { 
                  //make an offer 
                  myConnection.createOffer(function (offer) { 
                     console.log(offer); 

                     send({ 
                        type: "offer", 
                        offer: offer 
                     }); 

                     myConnection.setLocalDescription(offer); 
                  }, function (error) { 
                     alert("An error has occurred."); 
                  }); 
               } 
            });

            //when somebody wants to call us 
            function onOffer(offer, name) { 
               connectedUser = name; 
               myConnection.setRemoteDescription(new RTCSessionDescription(offer));

               myConnection.createAnswer(function (answer) { 
                  myConnection.setLocalDescription(answer); 

                  send({ 
                     type: "answer", 
                     answer: answer 
                  }); 

               }, function (error) { 
                  alert("oops...error"); 
               }); 
            }

            //when another user answers to our offer 
            function onAnswer(answer) { 
               myConnection.setRemoteDescription(new RTCSessionDescription(answer)); 
            }

            //when we got ice candidate from another user 
            function onCandidate(candidate) { 
               myConnection.addIceCandidate(new RTCIceCandidate(candidate)); 
            }


            //creating data channel 
            function openDataChannel() { 

               var dataChannelOptions = { 
                  reliable:true 
                };

               dataChannel = myConnection.createDataChannel("myDataChannel", dataChannelOptions);

               dataChannel.onerror = function (error) { 
                  console.log("Error:", error); 
               };

               dataChannel.onmessage = function (event) { 
                  console.log("Got message:", event.data); 
               };  
            }

            //when a user clicks the send message button 
            sendMsgBtn.addEventListener("click", function (event) { 
               console.log("send message");
               var val = msgInput.value; 
               dataChannel.send(val); 
            });


来源:https://stackoverflow.com/questions/37026849/rtcdatachannel-send-method-not-sending-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!