JSFiddle - React, Tailwind, and code Playground
JavaScript
// parseCandidate from https://github.com/fippo/sdp
function parseCandidate(line) {
var parts;
// Parse both variants.
if (line.indexOf('a=candidate:') === 0) {
parts = line.substring(12).split(' ');
} else {
parts = line.substring(10).split(' ');
}
var candidate = {
foundation: parts[0],
component: parts[1],
protocol: parts[2].toLowerCase(),
priority: parseInt(parts[3], 10),
ip: parts[4],
port: parseInt(parts[5], 10),
// skip parts[6] == 'typ'
type: parts[7]
};
for (var i = 8; i < parts.length; i += 2) {
switch (parts[i]) {
case 'raddr':
candidate.relatedAddress = parts[i + 1];
break;
case 'rport':
candidate.relatedPort = parseInt(parts[i + 1], 10);
break;
case 'tcptype':
candidate.tcpType = parts[i + 1];
break;
default: // Unknown extensions are silently ignored.
break;
}
}
return candidate;
};
var candidates = {};
var pc = new RTCPeerConnection({iceServers: [
{urls: 'stun:stun2.l.google.com:19302'},
{urls: 'stun:stun2.l.google.com:19302'}
]});
pc.createDataChannel("foo");
pc.onicecandidate = function(e) {
if (e.candidate && e.candidate.candidate.indexOf('srflx') !== -1) {
var cand = parseCandidate(e.candidate.candidate);
if (!candidates[cand.relatedPort]) candidates[cand.relatedPort] = [];
candidates[cand.relatedPort].push(cand.port);
} else if (!e.candidate) {
if (Object.keys(candidates).length === 1) {
var ports = candidates[Object.keys(candidates)[0]];
console.log(ports.length === 1 ? 'normal nat' : 'symmetric nat');
}
}
};
pc.createOffer()
.then(offer => pc.setLocalDescription(offer))