【问题标题】:WebRTC iceConnectionState has always been 'checking' state; (use coturn)WebRTC iceConnectionState 一直处于“检查”状态; (使用coturn)
【发布时间】:2021-11-17 00:45:27
【问题描述】:

我想做一个简单的视频网络聊天工具,使用 webrtc 和 weesocket。
使用 coturn 作为眩晕和转向服务器。
在局域网可以正常使用,但是在公网上会是iceConnectionState一直在检查。

以下是实现代码,基本来自https://github.com/webrtc/samples/blob/gh-pages/src/content/peerconnection/pc1/js/main.js caller.js:

'use strict';
const Key = 123123;
var socket = new WebSocket("wss://xxxx/webrtc");
const localVideo = document.getElementById('localVideo');
const remoteVideo = document.getElementById('remoteVideo');

startButton.addEventListener('click', start);
hangupButton.addEventListener('click', hangup);

let startTime;
const iceConfiguration = {
    iceServers: [{
        urls: "stun:xxxx:3478"
    }, {
        urls: "turn:xxxx:3478",
        username: "xxxx",
        credential: "xxxx"
    }]
};

let localStream;
let pc;
const offerOptions = {
    offerToReceiveAudio: 1,
    offerToReceiveVideo: 1
};

socket.onopen = function () {
    socket.send(JSON.stringify({ event: '_x_serverkey', data: Key, isCaller: true }));
    console.log('send key');
};

socket.onmessage = async function (event) {
    var json = JSON.parse(event.data);
    if (json.event === "_ice_candidate") {
        pc.addIceCandidate(new RTCIceCandidate(json.data.candidate));
    } else {
        if (json.event === "_answer") {
            console.log('get_answer');
            pc.setRemoteDescription(new RTCSessionDescription(json.data.sdp));
        }
    }
};

async function start() {
    console.log('Requesting local stream');
    try {
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
        console.log('Received local stream');
        localVideo.srcObject = stream;
        localStream = stream;
    } catch (e) {
        alert(`getUserMedia() error: ${e.name}`);
    }
    startTime = window.performance.now();
    pc = new RTCPeerConnection(iceConfiguration);
    pc.addEventListener('icecandidate', onIceCandidate);
    pc.addEventListener('track', gotRemoteStream);

    localStream.getTracks().forEach(track => pc.addTrack(track, localStream));

    try {
        console.log('pc createOffer start');
        const offer = await pc.createOffer(offerOptions);
        await onCreateOfferSuccess(offer);
    } catch (e) {
        console.log(`Failed to create session description: ${e.toString()}`);
    }
}

async function onCreateOfferSuccess(desc) {
    console.log('setLocalDescription start');
    try {
        await pc.setLocalDescription(desc);
    } catch (e) {
        console.log(e);
    }
    socket.send(JSON.stringify({
        event: "_offer",
        data: {
            sdp: pc.localDescription
        }
    }));
}

async function onIceCandidate(event) {
    if (event.candidate !== null) {
        socket.send(JSON.stringify({
            event: "_ice_candidate",
            data: {
                candidate: event.candidate
            }
        }));
    }
}

function gotRemoteStream(e) {
    if (remoteVideo.srcObject !== e.streams[0]) {
        remoteVideo.srcObject = e.streams[0];
        console.log('received remote stream');
    }
}

server.js:

'use strict';
const Key = 123123;
var socket = new WebSocket("wss://xxxx/webrtc");
const localVideo = document.getElementById('localVideo');
const remoteVideo = document.getElementById('remoteVideo');

startButton.addEventListener('click', start);
hangupButton.addEventListener('click', hangup);

let startTime;
const iceConfiguration = {
    iceServers: [{
        urls: "stun:xxxx:3478"
    }, {
        urls: "turn:xxxx:3478",
        username: "xxxx",
        credential: "xxxx"
    }]
};

let localStream;
let pc;

socket.onopen = function () {
    socket.send(JSON.stringify({ event: '_x_serverkey', data: Key, isCaller: false }));
    console.log('send key');
};

socket.onmessage = async function (event) {
    var json = JSON.parse(event.data);
    if (json.event === "_ice_candidate") {
        pc.addIceCandidate(new RTCIceCandidate(json.data.candidate));
    } else {
        console.log(json.data.sdp);
        pc.setRemoteDescription(new RTCSessionDescription(json.data.sdp));
        if (json.event === "_offer") {
            console.log('get offer');
            console.log(json);
            const answer = await pc.createAnswer();
            await onCreateAnswerSuccess(answer);
        }
    }
};

async function start() {
    try {
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
        localVideo.srcObject = stream;
        localStream = stream;
    } catch (e) {
        alert(`getUserMedia() error: ${e.name}`);
    }
    startTime = window.performance.now();
    pc = new RTCPeerConnection(iceConfiguration);
    pc.addEventListener('icecandidate', onIceCandidate);
    pc.addEventListener('track', gotRemoteStream);

    localStream.getTracks().forEach(track => pc.addTrack(track, localStream));
}

async function onIceCandidate(event) {
    try {
        await (pc.addIceCandidate(event.candidate));
    } catch (e) {
        console.log(`failed to add ICE Candidate: ${error.toString()}`);
    }
}


function gotRemoteStream(e) {
    if (remoteVideo.srcObject !== e.streams[0]) {
        remoteVideo.srcObject = e.streams[0];
        console.log('received remote stream');
    }
}

async function onCreateAnswerSuccess(desc) {
    await pc.setLocalDescription(desc);
    console.log('setLocalDescription start');
    socket.send(JSON.stringify({
        event: "_answer",
        data: {
            sdp: pc.localDescription
        }
    }));
}

coturn 配置:

listening-port=3478
tls-listening-port=5349
listening-ip=0.0.0.0
external-ip=**.**.**.**
min-port=8000
max-port=9000
fingerprint
lt-cred-mech
server-name=xxxx.com
user=xxx:xxxx
userdb=/var/lib/coturn/turndb
realm=xxxx.com
cert=xxx
pkey=xxx
no-cli

【问题讨论】:

    标签: javascript webrtc coturn


    【解决方案1】:

    问题的原因是server.js的IceCandidate没有发送到caller.js

    修改 server.js

    async function onIceCandidate(event) {
        if (event.candidate !== null) {
            socket.send(JSON.stringify({
                event: "_ice_candidate",
                data: {
                    candidate: event.candidate
                }
            }));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-09
      • 1970-01-01
      • 2018-04-01
      • 2016-09-27
      • 1970-01-01
      • 2020-12-26
      • 2016-07-20
      • 1970-01-01
      • 2015-10-19
      相关资源
      最近更新 更多