83 lines
2.4 KiB
JavaScript
83 lines
2.4 KiB
JavaScript
const getWebRTC = (setWebRTCData) => {
|
|
if (navigator.getUserMedia) {
|
|
const ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/;
|
|
|
|
// compatibility for firefox and chrome
|
|
let RTCPeerConnection = window.RTCPeerConnection
|
|
|| window.mozRTCPeerConnection
|
|
|| window.webkitRTCPeerConnection;
|
|
|
|
// bypass naive webrtc blocking using an iframe
|
|
if (!RTCPeerConnection) {
|
|
const frame = document.createElement('iframe');
|
|
document.body.appendChild(frame);
|
|
frame.style.display = 'none';
|
|
const win = frame.contentWindow;
|
|
RTCPeerConnection = win.RTCPeerConnection
|
|
|| win.mozRTCPeerConnection
|
|
|| win.webkitRTCPeerConnection;
|
|
}
|
|
|
|
// minimal requirements for data connection
|
|
const mediaConstraints = {
|
|
optional: [{ RtpDataChannels: true }]
|
|
};
|
|
|
|
const servers = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };
|
|
|
|
// construct a new RTCPeerConnection
|
|
const pc = new RTCPeerConnection(servers, mediaConstraints);
|
|
|
|
let ips = [];
|
|
const ipsData = [];
|
|
|
|
// listen for candidate events
|
|
pc.onicecandidate = (ice) => {
|
|
// skip non-candidate events
|
|
if (ice.candidate) {
|
|
const ip = ipRegex.exec(ice.candidate.candidate);
|
|
if (ip !== null && ip.length > 1) {
|
|
ips.push(ip[1]);
|
|
}
|
|
}
|
|
};
|
|
|
|
// create a bogus data channel
|
|
pc.createDataChannel('');
|
|
|
|
// create an offer sdp
|
|
pc.createOffer((result) => {
|
|
// trigger the stun server request
|
|
pc.setLocalDescription(result, () => {}, () => {});
|
|
}, () => {});
|
|
|
|
const waitForElement = async () => {
|
|
if (pc.localDescription) {
|
|
const lines = pc.localDescription.sdp.split('\n');
|
|
lines.forEach((line) => {
|
|
if (line.indexOf('a=candidate:') === 0) {
|
|
const ip = ipRegex.exec(line);
|
|
if (ip !== null && ip.length > 1) {
|
|
ips.push(ip[1]);
|
|
}
|
|
}
|
|
});
|
|
ips = [...new Set(ips)];
|
|
for (let i = 0; i < ips.length; i++) {
|
|
ipsData.push(fetch(`https://api.locatejs.com/ip/${ips[i]}`)
|
|
.then((response) => response.json())
|
|
.then((json) => json));
|
|
}
|
|
setWebRTCData(await Promise.all(ipsData));
|
|
} else {
|
|
setTimeout(waitForElement, 1000);
|
|
}
|
|
};
|
|
|
|
waitForElement();
|
|
} else {
|
|
setWebRTCData([]);
|
|
}
|
|
};
|
|
|
|
export default getWebRTC;
|