WebRTC连接问题

时间:2017-12-05 15:35:41

标签: javascript webrtc

最近我一直在试验WebRTC。我试图真正地围绕它,同时看看我是否可以测试它。

所以我写了一个检查两件事的测试

  1. 连接是否一致?
  2. 同伴的数量是否会减慢连接速度,如果是这样,阈值会变得明显之前是什么?
  3. 我在测试中注意到的是(1)不是真的。我发现这个测试结果平均为100?

    中的10到20次传递

    我要求的是有人看一看并告诉我,如果我的测试写错了,或者找出失败的另一个原因。

    请注意,我只在Chrome 62上运行此功能,而冰服务器列表则来自https://github.com/DamonOehlman/freeice

    以下是我写的测试:

    const localStream = await navigator.mediaDevices.getUserMedia({video:true});
    const iceServers = [{
        urls: [
            "stun:stun.l.google.com:19302",
            "stun:stun1.l.google.com:19302",
            "stun:stun2.l.google.com:19302",
            "stun:stun3.l.google.com:19302",
            "stun:stun4.l.google.com:19302",
            "stun:stun.ekiga.net",
            "stun:stun.ideasip.com",
            "stun:stun.rixtelecom.se",
            "stun:stun.schlund.de",
            "stun:stun.stunprotocol.org:3478",
            "stun:stun.voiparound.com",
            "stun:stun.voipbuster.com",
            "stun:stun.voipstunt.com",
            "stun:stun.voxgratia.org"
        ]
    }]
    
    async function initExample(){
        try{
            // Init Local Connections
            var localConnection = new RTCPeerConnection({iceServers});
            var remoteConnection = new RTCPeerConnection({iceServers});
    
            // Create Data Channels
            var remoteDataChannel;// this is added later
            var localDataChannel = localConnection.createDataChannel('DataChannel');
    
            // Configure Stream
            var remoteStream;// this is added later
            localConnection.addStream(localStream)
    
            // Catch DataChannel when it is sent from local to remote
            remoteConnection.ondatachannel = dataChannelEvent => {
                remoteDataChannel = dataChannelEvent.channel
            }
    
            // Catch MediaStream when it is sent from local to remote
            remoteConnection.onaddstream = mediaStreamEvent => {
                remoteStream = mediaStreamEvent.stream;
            }
    
            // Create Offer
            var offer = await localConnection.createOffer();
            await localConnection.setLocalDescription(offer);
            await remoteConnection.setRemoteDescription(localConnection.localDescription);
    
            // Create Answer
            var answer = await remoteConnection.createAnswer();
            await remoteConnection.setLocalDescription(answer);
            await localConnection.setRemoteDescription(remoteConnection.localDescription);
    
            // Return Results
            return {
                localConnection, remoteConnection,
                localDataChannel, localStream,
                get remoteDataChannel(){
                    return remoteDataChannel
                },
                get remoteStream(){
                    return remoteStream;
                },
            }
        }catch(e){
            console.error(e)
        }
    }
    
    async function test(N=100){
        const stats = {pass:0, fail: 0, N};
        const results = [];
        for (var i = 0; i < N; i++) {
            console.log({...stats, i})
            let conn = await initExample();
            if(conn.remoteDataChannel){
                stats.pass++;
            }else{
                stats.fail++;
            }
            results.push(conn);
        }
        return results;
    }
    
    var r = await test();
    

1 个答案:

答案 0 :(得分:0)

所以在@JTejedor评论和建议之后,我意识到我的连接测试设置不正确。对于遇到此问题的任何人,请注意,您需要确保同行正在将他们注册的冰候选人发送给彼此。

在我的离线版本中,完成如下:

// Map Ice Candidate
remoteConnection.onicecandidate = evt => {
    if(evt.candidate) {
        localConnection.addIceCandidate(evt.candidate)
    }
}
localConnection.onicecandidate = evt => {
    if(evt.candidate) {
        remoteConnection.addIceCandidate(evt.candidate)
    }
}

如果您使用套接字(或其他一些服务器端解决方案),请确保通过套接字将其发送给其他对等方。

这是工作测试(总是通过):

// Ice Servers
const iceServers = [{
    urls: [
        "stun:stun.l.google.com:19302",
        "stun:stun1.l.google.com:19302",
        "stun:stun2.l.google.com:19302",
        "stun:stun3.l.google.com:19302",
        "stun:stun4.l.google.com:19302",
        "stun:stun.ekiga.net",
        "stun:stun.ideasip.com",
        "stun:stun.rixtelecom.se",
        "stun:stun.schlund.de",
        "stun:stun.stunprotocol.org:3478",
        "stun:stun.voiparound.com",
        "stun:stun.voipbuster.com",
        "stun:stun.voipstunt.com",
        "stun:stun.voxgratia.org"
    ]
}]

// Run the test once
async function initExample(){
    // Init Local Connections
    var localConnection = new RTCPeerConnection({iceServers});
    var remoteConnection = new RTCPeerConnection({iceServers});//this is really "remote" its simulated

    // Map Ice Candidate
    remoteConnection.onicecandidate = evt => {
        if(evt.candidate) {
            localConnection.addIceCandidate(evt.candidate)
        }
    }
    localConnection.onicecandidate = evt => {
        if(evt.candidate) {
            remoteConnection.addIceCandidate(evt.candidate)
        }
    }

    // Create Data Channels
    var remoteDataChannel;// this is added later
    var localDataChannel = localConnection.createDataChannel('DataChannel');

    // Tie end of promise to getting the datachannel
    return new Promise( async res => {
        // Catch DataChannel when it is sent from local to remote
        remoteConnection.ondatachannel = dataChannelEvent => {
            console.log('GOT CHANNEL', dataChannelEvent)
            remoteDataChannel = dataChannelEvent.channel
            res(remoteDataChannel);
        }

        // Create Offer
        var offer = await localConnection.createOffer();
        await localConnection.setLocalDescription(offer);
        await remoteConnection.setRemoteDescription(localConnection.localDescription);

        // Create Answer
        var answer = await remoteConnection.createAnswer();
        await remoteConnection.setLocalDescription(answer);
        await localConnection.setRemoteDescription(remoteConnection.localDescription);

    })
}

// A Promisified Timeout
const promisedTimeout = (timeout = 10000) => new Promise((resolve, reject) => {
  let wait = window.setTimeout(() => {
    window.clearTimeout(wait);
    resolve(false);
  }, timeout)
})

// Run the test N times
async function test(N=100){
    // Init variables
    const stats = {pass:0, fail: 0, N};
    const results = [];

    // Loop
    for (var i = 0; i <= N; i++) {
        // log
        console.log({...stats, i});

        // This will each example against a timeout, 
        // if the timeout finishes first, then this test will be marked as fail
        let pass = await Promise.race([
            initExample(),
            promisedTimeout()
        ]);
        if(pass) {
            stats.pass ++;
        }else{
            stats.fail ++;
        }
        results.push(pass);
    }
    return {results,stats};
}

// Run the test
test()