WebRTC video/audio calling failed 90% of time on different network but got success 90% on same network

醉酒当歌 提交于 2019-12-12 05:28:02

问题


I have created video chat app using webRTC and Django channel.My app working 90% of time properly when using it in the same network but fail when using it on a different network.I am not able to see a video of remote person when using it on a different network.

I used chrome://webrtc-internals/ to trace my webRTC response and I got iceconnectionstate : failed when called using different network

Below screenshot is taken when I got success in the same network

And after success also it gave addIceCandidateFailed error on the same network but video calling works properly and this error comes only in chrome but not in firefox. Below is the screenshot

Below is my STUN/TUNE server configuration which is free.I got this from one of the StackOverflow links.

 var peerConnectionConfig = {
        iceServers: [{
                urls: ["turn:173.194.72.127:19305?transport=udp",
                    "turn:[2404:6800:4008:C01::7F]:19305?transport=udp",
                    "turn:173.194.72.127:443?transport=tcp",
                    "turn:[2404:6800:4008:C01::7F]:443?transport=tcp"
                ],
                username: "CKjCuLwFEgahxNRjuTAYzc/s6OMT",
                credential: "u1SQDR/SQsPQIxXNWQT7czc/G4c="
            },
            {
                urls: ["stun:stun.l.google.com:19302"]
            }
        ]
    };

Below is my webRTC javascript code

$(function() {
    var initiator,pc;
    var isSender = false;
    var peerConnectionConfig = {
        iceServers: [{
                urls: ["turn:173.194.XX.127:19305?transport=udp",
                    "turn:[2404:XXXX:XXXX:C01::7F]:19305?transport=udp",
                    "turn:173.194.XX.127:443?transport=tcp",
                    "turn:[2404:XXXX:XXXX:C01::7F]:443?transport=tcp"
                ],
                username: "XXXXXXXXXX",
                credential: "YYYYYYYYYYY"
            },
            {
                urls: ["stun:stun.l.google.com:19302"]
            }
        ]
    };
    $.ajax({
        type: "GET",
        url: '/isRoomExist/?roomName=121' ,
        beforeSend: function() {},
        success: function(data) {
            data = JSON.parse(data);
            initiatorCtrl(data[0].flgInitiator);
        }
    });
    var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
    var chatsock = new ReconnectingWebSocket(ws_scheme + '://' + window.location.host + "/chat" + window.location.pathname);

    function initiatorCtrl(event) {
        if (event == "fullhouse") {
            alert("full house");
        }
        if (event == "initiator") {
            initiator = false;
            init();
        }
        if (event == "not initiator") {
            initiator = true;
            init();
        }
    }

    function init() {
        var constraints = {
            audio: true,
            video: true
        };
        getUserMedia(constraints, connect, fail);
    }

    function connect(stream) {
        pc = new RTCPeerConnection(peerConnectionConfig);

        if (stream) {
            pc.addStream(stream);
            $('#local').attachStream(stream);
        }

        pc.onaddstream = function(event) {
            $('#remote').attachStream(event.stream);
            logStreaming(true);
        };
        pc.onicecandidate = function(event) {
            if (event.candidate) {
                chatsock.send(JSON.stringify(event.candidate));
                isSender = true;
            }
        };
        if (initiator) {
            createOffer();
        } else {
            log('waiting for offer...');
        }
        logStreaming(false);

        chatsock.onmessage = function(event) {
            var signal1 = JSON.parse(event.data);
            var signal = JSON.parse(signal1);

            if (isSender) {
                isSender = false
            } else {
                if (signal.sdp) {
                    if (initiator) {
                        receiveAnswer(signal);
                    } else {
                        receiveOffer(signal);
                    }
                } else if (signal.candidate) {
                    pc.addIceCandidate(new RTCIceCandidate(signal));
                }
            }
        };
    }

    function createOffer() {
        pc.createOffer(function(offer) {
            pc.setLocalDescription(offer, function() {
                chatsock.send(JSON.stringify(offer));
                isSender = true;
            }, fail);
        }, fail);
    }

    function receiveOffer(offer) {
        pc.setRemoteDescription(new RTCSessionDescription(offer), function() {
            pc.createAnswer(function(answer) {
                pc.setLocalDescription(answer, function() {
                    chatsock.send(JSON.stringify(answer));
                    isSender = true;
                }, fail);
            }, fail);
        }, fail);
    }

    function receiveAnswer(answer) {
        pc.setRemoteDescription(new RTCSessionDescription(answer));
    }
    function log() {
        console.log(Array.prototype.join.call(arguments, ' '))
        console.log.apply(console, arguments);
    }
    function logStreaming(streaming) {
        $('#streaming').text(streaming ? '[streaming]' : '[..]');
    }
    function fail() {
        console.error.apply(console, arguments);
    }
    jQuery.fn.attachStream = function(stream) {
        this.each(function() {
            this.src = URL.createObjectURL(stream);
            this.play();
        });
    };


});

回答1:


As per your webrtc-internals, you are adding the remote candidates before setting the remote description.

Put the candidate's in a queue, until you receive the remote description.
After setting the remote description,
you can send local candidates to remote user from queue or from onicecandidate
and add the remote candidates to your pc.

Update:
The order of messages is in general not the same as the POST order from the other client because the POSTs are async and the server may handle candidates faster(just relay & smaller size) than offer/answer(need to handle routing/cdr/forking).

Queuing Remote Candidates: We need to process remote offer before adding the candidates.
Queuing Local Candidates: If call/offer is forked to multiple destinations(user logged in mobile's & browser's Or group calling), then only first answer will be accepted by initiator. So all receiving endpoints need to queue local candidates, until their answer got acknowledged.

Reference Example



来源:https://stackoverflow.com/questions/44198962/webrtc-video-audio-calling-failed-90-of-time-on-different-network-but-got-succe

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