JSFiddle - React, Tailwind, and code Playground
HTML
<h1 style="background-color: yellow" id="is-checking" class="result"> Checking </h1>
<h1 style="background-color: red" id="is-connected" class="result"> Hostname Resolved </h1>
<h1 style="background-color: green" id="is-failed" class="result"> Hostname Not Resolved </h1>
<form onkeydown="return event.key != 'Enter';">
Hostname To Lookup: <br>
<input type="text" id="hostname">
<br>
<input type="button" value="Query" onclick="window.checkHostname(document.getElementById('hostname').value)">
</form>
JavaScript
let answerPc = null, offerPc = null;
function hideAllResults() {
document.querySelectorAll('.result').forEach(el => {
el.style.display = 'none';
});
}
hideAllResults();
function updateForConnectionState(iceConnectionState) {
hideAllResults();
if ((el = document.querySelector(`#is-${iceConnectionState}`)) != null) {
el .style.display = 'block';
}
}
function rewriteCandidate(peerConnection, candidate, hostname) {
if (candidate == null) {
return;
}
peerConnection.addIceCandidate({
candidate: candidate.candidate.replace(/\S+\.\S+/, hostname),
sdpMid: candidate.sdpMid,
sdpMLineIndex: candidate.sdpMLineIndex,
})
}
window.checkHostname = hostname => {
if (!hostname.endsWith('.local')) {
hostname += '.local';
}
if (answerPc) {
answerPc.close();
offerPc.close();
}
updateForConnectionState('checking')
answerPc = new RTCPeerConnection();
offerPc = new RTCPeerConnection();
offerPc.createDataChannel('dummyChannel');
offerPc.oniceconnectionstatechange = () => updateForConnectionState(answerPc.iceConnectionState)
answerPc.oniceconnectionstatechange = () => updateForConnectionState(answerPc.iceConnectionState)
offerPc.onicecandidate = e => rewriteCandidate(answerPc, e.candidate, hostname)
answerPc.onicecandidate = e => rewriteCandidate(offerPc, e.candidate, hostname)
offerPc.createOffer().then(offer => {
offerPc.setLocalDescription(offer)
answerPc.setRemoteDescription(offer)
return answerPc.createAnswer()
}).then(answer => {
answerPc.setLocalDescription(answer)
offerPc.setRemoteDescription(answer)
}).catch(alert)
}