最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Webrtc Data Channel always in connecting state and not open - Stack Overflow

programmeradmin4浏览0评论

I am creating a small WebRTC app that for now used to exchange text message. I have got the WebRTC connection working but Datachannel always remains in "connecting" state and never goes to "Open".

Please tell me what I am missing here.

Following is the JS.

socket.onmessage = function(e){
            console.log("Message from signaling server");
                writeToScreen('<span class="server">Server: </span>'+e.data);
                var data = JSON.parse(e.data);
    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;
}


            }
            // Enable send and close button
            $('#send').prop('disabled', false);
            $('#close').prop('disabled', false);
            $('#connect').prop('disabled', true);
        }
        function close(){
            socket.close();
        }
        function writeToScreen(msg){
            var screen = $('#screen');
            screen.append('<p>'+msg+'</p>');
            screen.animate({scrollTop: screen.height()}, 10);
        }
        function clearScreen(){
            $('#screen').html('');
        }
        function sendMessage(){
            if(!socket || socket == undefined) return false;
            var mess = $.trim($('#message').val());
            if(mess == '') return;
            writeToScreen('<span class="client">Client: </span>'+mess);
            socket.send(mess);
            // Clear input
            $('#message').val('');
        }
        $(document).ready(function(){
            $('#message').focus();
            $('#frmInput').submit(function(){
                sendMessage();
            });
            $('#connect').click(function(){
                connect();
            });
            $('#close').click(function(){
                close();
            });
            $('#clear').click(function(){
                clearScreen();
            });
        });

        if (!window.RTCPeerConnection) {
    window.RTCPeerConnection = window.webkitRTCPeerConnection;
}

var configuration = {
  "iceServers": [
  {
    "urls": "stun:mmt-stun.verkstad"
  },
  {
    "urls": "turn:mmt-turn.verkstad",
    "username": "webrtc",
    "credential": "secret"
  }
  ]
};


myConnection = new RTCPeerConnection(configuration,{optional:[{RtpDataChannels: true},{DtlsSrtpKeyAgreement: true}]});

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

                //when the browser finds an ice candidate we send it to another peer

                myConnection.onicecandidate = function (event) {
                console.log(event.candidate);
                if (event.candidate) {
                    send({
                    type: "candidate",
                    candidate: event.candidate
                    });
                    }
                };  


// Datachannel

    var mediaConstraints = {
        'offerToReceiveAudio': 1,
        'offerToReceiveVideo': 1
    };


   var connectToOtherUsernameBtn =  document.getElementById("connectToOtherUsernameBtn");   
        console.log(connectToOtherUsernameBtn);

        connectToOtherUsernameBtn.addEventListener("click", function () {
        console.log("ice state : "+myConnection.iceGatheringState);
var otherUsername = connectToOtherUsernameBtn.value;
connectedUser = otherUsername;
        if (otherUsername.length > 0) {
        //make an offer

        myConnection.createOffer(function (offer) {
        send({
        type: "offer",
        offer: offer
        });
        console.log(offer);
        console.log(typeof(offer));
        myConnection.setLocalDescription(offer);
        console.log("localDescription");
        console.log(myConnection.localDescription);
        }, function (error) {
        alert("An error has occurred.");
        console.log(error);
        });
        }
        });


function send(message) {
if (connectedUser) {
message.name = connectedUser;
 }
socket.send(JSON.stringify(message));
};

//when somebody wants to call us
function onOffer(offer, name) {
console.log("offer recieved");
connectedUser = name;
 myConnection.setRemoteDescription(new RTCSessionDescription(offer));
 myConnection.createAnswer(function (answer) {
 myConnection.setLocalDescription(answer);
 send({
 type: "answer",
 answer: answer
 });
 }, function (error) {
 alert("oops...error");
 console.log(error);
 });
  console.log("Answer sent");
}

//when another user answers to our offer
function onAnswer(answer) {
console.log("answer recieved");
myConnection.setRemoteDescription(new RTCSessionDescription(answer));
console.log(myConnection.iceConnectionState );
}
//when we got ice candidate from another user
function onCandidate(candidate) {
myConnection.addIceCandidate(new RTCIceCandidate(candidate));
}


}); 

//data channel

//creating data channel
function openDataChannel() {
console.log("opening Data Channel");
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);
 };
}



function sendmsg() {
console.log("send message");
var msgInput=document.getElementById("msgInput");
var val = msgInput.value;
console.log(val);
 dataChannel.send(val);
}




function checkstatus(){
console.log("Checking Status");
console.log("signalingState: "+myConnection.signalingState);
console.log("iceConnectionState: "+myConnection.iceConnectionState);
console.log("iceGatheringState: "+myConnection.iceGatheringState);
console.log("localDescription: ");
console.log(myConnection.localDescription);
console.log("remoteDescription:");
console.log(myConnection.remoteDescription);
console.log("Connestion id");
console.log(dataChannel.id);
console.log("Connestion readyState");
console.log(dataChannel.readyState);
}

Following is the console log from chrome.

I am creating a small WebRTC app that for now used to exchange text message. I have got the WebRTC connection working but Datachannel always remains in "connecting" state and never goes to "Open".

Please tell me what I am missing here.

Following is the JS.

socket.onmessage = function(e){
            console.log("Message from signaling server");
                writeToScreen('<span class="server">Server: </span>'+e.data);
                var data = JSON.parse(e.data);
    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;
}


            }
            // Enable send and close button
            $('#send').prop('disabled', false);
            $('#close').prop('disabled', false);
            $('#connect').prop('disabled', true);
        }
        function close(){
            socket.close();
        }
        function writeToScreen(msg){
            var screen = $('#screen');
            screen.append('<p>'+msg+'</p>');
            screen.animate({scrollTop: screen.height()}, 10);
        }
        function clearScreen(){
            $('#screen').html('');
        }
        function sendMessage(){
            if(!socket || socket == undefined) return false;
            var mess = $.trim($('#message').val());
            if(mess == '') return;
            writeToScreen('<span class="client">Client: </span>'+mess);
            socket.send(mess);
            // Clear input
            $('#message').val('');
        }
        $(document).ready(function(){
            $('#message').focus();
            $('#frmInput').submit(function(){
                sendMessage();
            });
            $('#connect').click(function(){
                connect();
            });
            $('#close').click(function(){
                close();
            });
            $('#clear').click(function(){
                clearScreen();
            });
        });

        if (!window.RTCPeerConnection) {
    window.RTCPeerConnection = window.webkitRTCPeerConnection;
}

var configuration = {
  "iceServers": [
  {
    "urls": "stun:mmt-stun.verkstad"
  },
  {
    "urls": "turn:mmt-turn.verkstad",
    "username": "webrtc",
    "credential": "secret"
  }
  ]
};


myConnection = new RTCPeerConnection(configuration,{optional:[{RtpDataChannels: true},{DtlsSrtpKeyAgreement: true}]});

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

                //when the browser finds an ice candidate we send it to another peer

                myConnection.onicecandidate = function (event) {
                console.log(event.candidate);
                if (event.candidate) {
                    send({
                    type: "candidate",
                    candidate: event.candidate
                    });
                    }
                };  


// Datachannel

    var mediaConstraints = {
        'offerToReceiveAudio': 1,
        'offerToReceiveVideo': 1
    };


   var connectToOtherUsernameBtn =  document.getElementById("connectToOtherUsernameBtn");   
        console.log(connectToOtherUsernameBtn);

        connectToOtherUsernameBtn.addEventListener("click", function () {
        console.log("ice state : "+myConnection.iceGatheringState);
var otherUsername = connectToOtherUsernameBtn.value;
connectedUser = otherUsername;
        if (otherUsername.length > 0) {
        //make an offer

        myConnection.createOffer(function (offer) {
        send({
        type: "offer",
        offer: offer
        });
        console.log(offer);
        console.log(typeof(offer));
        myConnection.setLocalDescription(offer);
        console.log("localDescription");
        console.log(myConnection.localDescription);
        }, function (error) {
        alert("An error has occurred.");
        console.log(error);
        });
        }
        });


function send(message) {
if (connectedUser) {
message.name = connectedUser;
 }
socket.send(JSON.stringify(message));
};

//when somebody wants to call us
function onOffer(offer, name) {
console.log("offer recieved");
connectedUser = name;
 myConnection.setRemoteDescription(new RTCSessionDescription(offer));
 myConnection.createAnswer(function (answer) {
 myConnection.setLocalDescription(answer);
 send({
 type: "answer",
 answer: answer
 });
 }, function (error) {
 alert("oops...error");
 console.log(error);
 });
  console.log("Answer sent");
}

//when another user answers to our offer
function onAnswer(answer) {
console.log("answer recieved");
myConnection.setRemoteDescription(new RTCSessionDescription(answer));
console.log(myConnection.iceConnectionState );
}
//when we got ice candidate from another user
function onCandidate(candidate) {
myConnection.addIceCandidate(new RTCIceCandidate(candidate));
}


}); 

//data channel

//creating data channel
function openDataChannel() {
console.log("opening Data Channel");
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);
 };
}



function sendmsg() {
console.log("send message");
var msgInput=document.getElementById("msgInput");
var val = msgInput.value;
console.log(val);
 dataChannel.send(val);
}




function checkstatus(){
console.log("Checking Status");
console.log("signalingState: "+myConnection.signalingState);
console.log("iceConnectionState: "+myConnection.iceConnectionState);
console.log("iceGatheringState: "+myConnection.iceGatheringState);
console.log("localDescription: ");
console.log(myConnection.localDescription);
console.log("remoteDescription:");
console.log(myConnection.remoteDescription);
console.log("Connestion id");
console.log(dataChannel.id);
console.log("Connestion readyState");
console.log(dataChannel.readyState);
}

Following is the console log from chrome.

Share Improve this question asked Jan 20, 2017 at 17:58 user2288650user2288650 4501 gold badge8 silver badges24 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

remove {RtpDataChannels: true} try again and if it works burn the tutorial or book which remended those "rtp data channels". They are broken.

I had the same problem. my code was working fine on mozilla using localhost signalling server without internet but on chrome i had this problem. Its Trickle ICE problem. one solution is you may set trickle ice off.

In chrome, may be you need the internet connection to gather the all possible ICE candidates. because in Chrome Datachannel will not get opened untill peer get all possible ICE candidates.

you can try the following link with internet or without internet. you will have brief idea. https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

for further information you can check this https://webrtcstandards.info/webrtc-trickle-ice/

My data channel was stuck in the connecting state because I had the block of code which creates the data channel (and initialized the callbacks onopen, onmessage, etc) was BELOW the peerConnection.setLocalDescription() method.

I had to move initialization of the data channel callback all the way up ABOVE the SDP Offer/Answer Exchange.

Example - before (wrong):

...

const offerDescription = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offerDescription);

...

dataChannel = peerConnection.createDataChannel('myArbitraryChannelName');
dataChannel.onopen = () => { ... };
dataChannel.onmessage = () => { ... };
dataChannel.onclose = () => { ... };

Example - after (correct):

dataChannel = peerConnection.createDataChannel('myArbitraryChannelName');
dataChannel.onopen = () => { ... };
dataChannel.onmessage = () => { ... };
dataChannel.onclose = () => { ... };

...

const offerDescription = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offerDescription);

...
发布评论

评论列表(0)

  1. 暂无评论