简体   繁体   English

JavaScript通过WebRTC捕获IP(通过异步/等待发出)

[英]JavaScript to capture IP via WebRTC (issue with async/await)

I have came up with code that capture IPs via WebRTC. 我想出了通过WebRTC捕获IP的代码。 However I have run into issue, I can't return IPs as variable, I'm able only print IPs in console, show them in alert or show them on HTML page. 但是我遇到了问题,我无法将IP作为变量返回,我只能在控制台中打印IP,在警报中显示它们或在HTML页面上显示它们。 But I need return IPs as variable from function. 但是我需要从函数返回IP作为变量。

I believe issue is in async/awaiting. 我认为问题出在异步/等待中。 I'm not JavaScript developer and it will took whole day to find out a place where to put await . 我不是JavaScript开发人员,需要一整天的时间才能找到可以await的地方。

Please help me solve this issue. 请帮我解决这个问题。 Thank you. 谢谢。

function findIPsWithWebRTC() {
    var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
    var pc = new myPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]}),
    noop = function() {},
    IPs = {},
    ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
    key;

    function ipIterate(ip) {
        if (!IPs[ip]) console.log('got ip: ', ip);
        IPs[ip] = true;
    }

    pc.createDataChannel("");

    pc.createOffer(function(sdp) {
        sdp.sdp.split('\n').forEach(function(line) {
            if (line.indexOf('candidate') < 0) return;
            line.match(ipRegex).forEach(ipIterate);
        });
        pc.setLocalDescription(sdp, noop, noop);
    }, noop);

    pc.onicecandidate = function(ice) {
        if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
        ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
    };

    console.log("ips: " + JSON.stringify(IPs));
    return {
        "source": "WebRTC",
        "name": "IPs",
        "value": JSON.stringify(IPs)
    }
}

alert(findIPsWithWebRTC().value);

I can output IPs in console, but I can't return IPs as value from function. 我可以在控制台中输出IP,但不能从功能返回IP作为值。

在此处输入图片说明

findIPsWithWebRTC can't return the IPs, because the IPs are provided to your code asynchronously. findIPsWithWebRTC 无法返回IP,因为IP是异步提供给您的代码的。 A synchronous function cannot return the result of an asynchronous process. 同步函数无法返回异步过程的结果。

Instead, your findIPsWithWebRTC should return a promise , which will be fulfilled with the object your currently trying to return. 相反,您的findIPsWithWebRTC应该返回一个promise ,这将通过您当前尝试返回的对象来实现。 It looks like you get the IPs in in onicecandidate (or perhaps the callback to createOffer ?), so (see *** ): 看起来您在onicecandidate (或者也许是createOffer的回调?)中获得了IP,因此(请参阅*** ):

function findIPsWithWebRTC() {
    // *** Return a promise
    return new Promise((resolve, reject) => {
        var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
        var pc = new myPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]}),
        noop = function() {},
        IPs = {},
        ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
        key;

        function ipIterate(ip) {
            if (!IPs[ip]) console.log('got ip: ', ip);
            IPs[ip] = true;
        }

        pc.createDataChannel("");

        pc.createOffer(function(sdp) {
            sdp.sdp.split('\n').forEach(function(line) {
                if (line.indexOf('candidate') < 0) return;
                line.match(ipRegex).forEach(ipIterate);
            });
            pc.setLocalDescription(sdp, noop, noop);
            // *** Resolve the promise? Or see below.
            resolve({
                "source": "WebRTC",
                "name": "IPs",
                "value": JSON.stringify(IPs)
            });
        }, noop);

        pc.onicecandidate = function(ice) {
            if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
            ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
            // *** Resolve the promise? Or see above.
            resolve({
                "source": "WebRTC",
                "name": "IPs",
                "value": JSON.stringify(IPs)
            });
        };
    });
}

Presumably there's also a way for this to fail. 大概还有一种失败的方法。 You'll want to call reject in that case, so that the promise doesn't stay unsettled forever. 在这种情况下,您将需要打电话给reject ,这样诺言就不会永远保持不变。

Code using findIPsWithWebRTC will need to handle the fact that it provides a promise. 使用findIPsWithWebRTC代码将需要处理它提供承诺的事实。 You can either consume it within an async function: 您可以在async函数中使用它:

// In an `async` function
try {
    const ipInfo = await findIPsWithWebRTC();
    // ...use `ipInfo`...
} catch (error) {
    // Handle/report error
}

...or in a non- async function, use then and catch : ...或者在非async函数中,使用thencatch

findIPsWithWebRTC()
.then(ipInfo => {
    // ...use `ipInfo`...
})
.catch(error => {
    // Handle/report error
});

In both cases, if the function consuming the result isn't the top-level consumer, you would normally leave error handling to it. 在这两种情况下,如果使用结果的函数都不是顶级消费者,则通常会对其进行错误处理。 In the async example, you'd do that by not having the try / catch (rejections are automatically propagated to the caller). async示例中,您可以通过不使用try / catch做到这一点(拒绝会自动传播到调用方)。 In the non- async example, you'd do it by returning the result of calling then and not having catch . 在非async示例中,您可以通过返回then且没有catch的结果来实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM