WebRTC获取candidate以及candidate中出现xxx.local
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
文章目录
获取candidate
我们可以去这个网址查看当前集群能获取到的candidate列表。
- https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
配置Stun、Turn服务
可选章节一般情况Stun服务部署在外网用于获取机器的外网地址。如果是纯内网环境可以不要这个。
Turn服务用于网络不通的2台机器用于流量转发用的。可以部署在外网也可以再内网。
- 部署在外网可以跨Nat转发。
- 部署在内网只可以转发内网。
默认搜集
可以看到上图中收集的地址为xxx.local
这是什么呢简单来说就是2019年之前默认可以直接获取到机器的IP地址但是由于这里存在安全问题所以之后默认改为xxx.local
这是mDNS即内网多播类型的DNS协议相当于是加了密的IP。
更改Chrome设置再次搜集
上面的情况不方便调试我们可以去更改默认配置把它设置为Disabled
设置方式如下命令
chrome://flags/#enable-webrtc-hide-local-ips-with-mdns
设置为Disabled
之后别忘了Relaunch
浏览器。再次搜集candidates结果如下
变为了IPV4和IPV6地址。但是跟本地的
ipconfig
命令获取的还少了些比如我本地的一些虚拟网卡地址。
更改获取音视频权限设置再次搜集
具体操作如下图更改完成后刷新页面然后再次收集。
搜集结果如下
会把所有网卡信息都收集且会同时提供TCP协议的端口。
测试代码
自己整理了可以简单测试的代码如下。
<!DOCTYPE html>
<html>
<head>
<title>example</title>
</head>
<body>
<h2>example</h2>
<div id="laker">
<table id="candidates" border="2">
<thead id="candidatesHead">
<tr>
<th>Time</th>
<th>Type</th>
<th>Foundation</th>
<th>Protocol</th>
<th>Address</th>
<th>Port</th>
<th>Priority</th>
<th>URL (if present)</th>
<th>relayProtocol (if present)</th>
</tr>
</thead>
<tbody id="candidatesBody"></tbody>
</table>
</div>
<script>
const candidateTBody = document.querySelector('tbody#candidatesBody');
const config = {
iceServers: [
{ urls: "stun:stun.l.google.com:19302" },
{ urls: "stun:global.stun.twilio.com:3478?transport=udp" }
],
iceTransportPolicy: "all",
};
const offerOptions = { offerToReceiveAudio: 1 };
let desc;
try {
pc = new RTCPeerConnection(config);
pc.onicecandidate = iceCallback;
pc.onicegatheringstatechange = gatheringStateChange;
pc.onicecandidateerror = iceCandidateError;
desc = pc.createOffer(offerOptions);
} catch (err) {
console.log(err)
}
let begin = window.performance.now();
pc.setLocalDescription(desc);
let lakerhtml = '';
async function iceCallback(event) {
const elapsed = ((window.performance.now() - begin) / 1000).toFixed(3);
const row = document.createElement('tr');
if (event.candidate) {
if (event.candidate.candidate === '') {
return;
}
appendCell(row, elapsed);
lakerhtml += event.candidate.candidate + "<BR>"
const { candidate } = event;
let url;
// Until url is available from the candidate, to to polyfill.
if (['srflx', 'relay'].includes(candidate.type) && !candidate.url) {
const stats = await pc.getStats();
stats.forEach(report => {
if (!url && report.type === 'local-candidate' &&
report.address === candidate.address &&
report.port === candidate.port) {
url = report.url;
}
});
}
appendCell(row, candidate.type);
appendCell(row, candidate.foundation);
appendCell(row, candidate.protocol);
appendCell(row, candidate.address);
appendCell(row, candidate.port);
appendCell(row, formatPriority(candidate.priority));
appendCell(row, candidate.url || url || '');
appendCell(row, candidate.relayProtocol || '');
}
candidateTBody.appendChild(row);
}
function gatheringStateChange() {
console.log(pc.iceGatheringState)
if (pc.iceGatheringState !== 'complete') {
return;
}
document.querySelector('#laker').innerHTML = lakerhtml
pc.close();
pc = null;
}
function iceCandidateError(e) {
console.log(e)
}
function appendCell(row, val) {
const cell = document.createElement('td');
cell.textContent = val;
row.appendChild(cell);
}
// 将 uint32 PRIORITY 字段解析为其来自 RFC 5245 的组成部分
// 类型首选项、local首选项和组件ID。
// 例如126 | 32252 | 255126 是host首选项255是组件ID
function formatPriority(priority) {
return [
priority >> 24,
(priority >> 8) & 0xFFFF,
priority & 0xFF
].join(' | ');
}
</script>
</body>
</html>