Skip to content

Instantly share code, notes, and snippets.

@Iftimie
Last active January 30, 2022 11:42
Show Gist options
  • Save Iftimie/242a9c4c515490761e14f9690b810f62 to your computer and use it in GitHub Desktop.
Save Iftimie/242a9c4c515490761e14f9690b810f62 to your computer and use it in GitHub Desktop.
WebRTC
<html>
<head>
<title>WebRTC</title>
<script type="module">
import * as common from './common.js';
async function start() {
const peerConnection = initializeBeforeReceivingOffer()
await receiveOfferSDP(peerConnection)
await sendAnswerSDP(peerConnection)
}
function initializeBeforeReceivingOffer() {
const peerConnection = new RTCPeerConnection()
common.addConnectionStateHandler(peerConnection)
return peerConnection
}
async function receiveOfferSDP(peerConnection) {
const remoteOfferString = prompt("Peer offer");
const remoteOffer = new RTCSessionDescription(JSON.parse(remoteOfferString))
await peerConnection.setRemoteDescription(remoteOffer)
}
async function sendAnswerSDP(peerConnection) {
const localAnswer = await peerConnection.createAnswer()
peerConnection.setLocalDescription(localAnswer)
await common.waitForAllICE(peerConnection)
const localAnswerWithICECandidates = peerConnection.localDescription
console.log("localAnswerWithICECandidates:")
console.log(JSON.stringify(localAnswerWithICECandidates))
}
start()
</script>
</head>
<body>
<h1>Hi! Check the console!</h1>
</body>
</html>
<html>
<head>
<title>WebRTC</title>
<script type="module">
import * as common from './common.js';
async function start() {
const peerConnection = initializeBeforeCreatingOffer()
await prepareOfferSDP(peerConnection)
await receiveAnswerSDP(peerConnection)
}
function initializeBeforeCreatingOffer() {
const peerConnection = new RTCPeerConnection()
common.addConnectionStateHandler(peerConnection)
peerConnection.createDataChannel(common.CHAT_CHANNEL)
return peerConnection
}
async function prepareOfferSDP(peerConnection) {
const localOffer = await peerConnection.createOffer()
await peerConnection.setLocalDescription(localOffer)
await common.waitForAllICE(peerConnection)
const localOfferWithICECandidates = peerConnection.localDescription
console.log("localOfferWithICECandidates:")
console.log(JSON.stringify(localOfferWithICECandidates))
}
async function receiveAnswerSDP(peerConnection) {
console.log("Will wait for answer")
const remoteAnswerString = prompt("Peer answer");
const remoteAnswer = JSON.parse(remoteAnswerString)
peerConnection.setRemoteDescription(remoteAnswer)
}
console.log("\n".repeat(10))
start()
</script>
</head>
<body>
<h1>Hi! Check the console!</h1>
</body>
</html>
export const CHAT_CHANNEL = "chat"
export function waitForAllICE(peerConnection) {
return new Promise((fufill, reject) => {
peerConnection.onicecandidate = (iceEvent) => {
if (iceEvent.candidate === null) fufill()
}
setTimeout(() => reject("Waited too long for ice candidates"), 1000)
})
}
export function addConnectionStateHandler(peerConnection) {
peerConnection.onconnectionstatechange = function () {
console.log(peerConnection.connectionState)
};
}
<html>
<head>
<title>WebRTC</title>
<script type="module">
import * as common from './common.js';
async function start() {
const peerConnection = initializeBeforeReceivingOffer()
await receiveOfferSDP(peerConnection)
await sendAnswerSDP(peerConnection)
const dataChannel = await waitForDataChannel(peerConnection)
console.log("Sending message, check the other tab")
dataChannel.send("World")
}
function initializeBeforeReceivingOffer() {
const peerConnection = new RTCPeerConnection()
common.addConnectionStateHandler(peerConnection)
return peerConnection
}
async function receiveOfferSDP(peerConnection) {
const remoteOfferString = prompt("Peer offer");
const remoteOffer = new RTCSessionDescription(JSON.parse(remoteOfferString))
await peerConnection.setRemoteDescription(remoteOffer)
}
async function sendAnswerSDP(peerConnection) {
const localAnswer = await peerConnection.createAnswer()
peerConnection.setLocalDescription(localAnswer)
await common.waitForAllICE(peerConnection)
const localAnswerWithICECandidates = peerConnection.localDescription
console.log("localAnswerWithICECandidates:")
console.log(JSON.stringify(localAnswerWithICECandidates))
}
function waitForDataChannel(peerConnection) {
return common.waitForEvent((fulfill) => {
peerConnection.ondatachannel = function (e) {
const dataChannel = e.channel
dataChannel.onmessage = function (e) {
console.log("Received message: ", e.data)
};
fulfill(dataChannel)
}
})
}
start()
</script>
</head>
<body>
<h1>Hi! Check the console!</h1>
</body>
</html>
<html>
<head>
<title>WebRTC</title>
<script type="module">
import * as common from './common.js';
async function start() {
const [peerConnection, dataChannel] = initializeBeforeCreatingOffer()
await prepareOfferSDP(peerConnection)
await receiveAnswerSDP(peerConnection)
await sendMessage(dataChannel)
}
function initializeBeforeCreatingOffer() {
const peerConnection = new RTCPeerConnection()
common.addConnectionStateHandler(peerConnection)
const dataChannel = peerConnection.createDataChannel(common.CHAT_CHANNEL)
dataChannel.onmessage = function (e) {
console.log("Received message: ", e.data)
};
return [peerConnection, dataChannel]
}
async function prepareOfferSDP(peerConnection) {
const localOffer = await peerConnection.createOffer()
await peerConnection.setLocalDescription(localOffer)
await common.waitForAllICE(peerConnection)
const localOfferWithICECandidates = peerConnection.localDescription
console.log("localOfferWithICECandidates:")
console.log(JSON.stringify(localOfferWithICECandidates))
}
async function receiveAnswerSDP(peerConnection) {
console.log("Will wait for answer")
const remoteAnswerString = prompt("Peer answer");
const remoteAnswer = JSON.parse(remoteAnswerString)
peerConnection.setRemoteDescription(remoteAnswer)
}
async function sendMessage(dataChannel) {
await waitForDataChannelOpen(dataChannel)
console.log("Sending message. Check the other tab")
dataChannel.send("Hello")
}
function waitForDataChannelOpen(dataChannel) {
return common.waitForEvent((fulfill) => {
dataChannel.onopen = function() {
if (dataChannel.readyState == "open") {
fulfill()
}
};
})
}
console.log("\n".repeat(10))
start()
</script>
</head>
<body>
<h1>Hi! Check the console!</h1>
</body>
</html>
export const CHAT_CHANNEL = "chat"
export function waitForAllICE(peerConnection) {
return waitForEvent((fulfill) => {
peerConnection.onicecandidate = (iceEvent) => {
if (iceEvent.candidate === null)
fulfill()
}
})
}
export function waitForEvent(user_function) {
return new Promise((fulfill, reject) => {
user_function(fulfill)
setTimeout(() => reject("Waited too long"), 60000)
})
}
export function addConnectionStateHandler(peerConnection) {
peerConnection.onconnectionstatechange = function () {
console.log(peerConnection.connectionState)
};
}
<html>
<head>
<title>WebRTC</title>
<script type="module">
import * as common from './common.js';
async function start() {
const peerConnection = initializeBeforeReceivingOffer()
await receiveOfferSDP(peerConnection)
await sendAnswerSDP(peerConnection)
receiveIceCandidates(peerConnection)
const dataChannel = await waitForDataChannel(peerConnection)
console.log("Sending message, check the other tab")
dataChannel.send("World")
}
function initializeBeforeReceivingOffer() {
const peerConnection = new RTCPeerConnection()
common.addConnectionStateHandler(peerConnection)
return peerConnection
}
async function receiveOfferSDP(peerConnection) {
const remoteOfferString = prompt("Peer offer");
const remoteOffer = new RTCSessionDescription(JSON.parse(remoteOfferString))
await peerConnection.setRemoteDescription(remoteOffer)
}
async function sendAnswerSDP(peerConnection) {
const localAnswer = await peerConnection.createAnswer()
peerConnection.setLocalDescription(localAnswer)
console.log("localAnswerWithoutICECandidates:")
console.log(JSON.stringify(localAnswer))
}
function receiveIceCandidates(peerConnection) {
const remoteIceCandidatesString = prompt("Peer iceCandidates");
const remoteIceCandidates = JSON.parse(remoteIceCandidatesString)
remoteIceCandidates.map(iceCandidate => {
peerConnection.addIceCandidate(iceCandidate)
})
}
function waitForDataChannel(peerConnection) {
return common.waitForEvent((fulfill) => {
peerConnection.ondatachannel = function (e) {
const dataChannel = e.channel
dataChannel.onmessage = function (e) {
console.log("Received message: ", e.data)
};
fulfill(dataChannel)
}
})
}
start()
</script>
</head>
<body>
<h1>Hi! Check the console!</h1>
</body>
</html>
<html>
<head>
<title>WebRTC</title>
<script type="module">
import * as common from './common.js';
async function start() {
const [peerConnection, dataChannel] = initializeBeforeCreatingOffer()
await prepareOfferSDP(peerConnection)
await receiveAnswerSDP(peerConnection)
await sendIceCandidates(peerConnection)
await sendMessage(dataChannel)
}
function initializeBeforeCreatingOffer() {
const peerConnection = new RTCPeerConnection()
common.addConnectionStateHandler(peerConnection)
const dataChannel = peerConnection.createDataChannel(common.CHAT_CHANNEL)
dataChannel.onmessage = function (e) {
console.log("Received message: ", e.data)
};
return [peerConnection, dataChannel]
}
async function prepareOfferSDP(peerConnection) {
const localOffer = await peerConnection.createOffer()
await peerConnection.setLocalDescription(localOffer)
console.log("localOfferWithoutICECandidates:")
console.log(JSON.stringify(localOffer))
}
async function receiveAnswerSDP(peerConnection) {
console.log("Will wait for answer")
const remoteAnswerString = prompt("Peer answer");
const remoteAnswer = JSON.parse(remoteAnswerString)
peerConnection.setRemoteDescription(remoteAnswer)
}
async function sendIceCandidates(peerConnection) {
const iceCandidatesList = []
await common.collectAllICE(peerConnection, iceCandidatesList)
console.log("iceCandidatesList:")
console.log(JSON.stringify(iceCandidatesList))
}
async function sendMessage(dataChannel) {
await waitForDataChannelOpen(dataChannel)
console.log("Sending message. Check the other tab")
dataChannel.send("Hello")
}
function waitForDataChannelOpen(dataChannel) {
return common.waitForEvent((fulfill) => {
dataChannel.onopen = function() {
if (dataChannel.readyState == "open") {
fulfill()
}
};
})
}
console.log("\n".repeat(10))
start()
</script>
</head>
<body>
<h1>Hi! Check the console!</h1>
</body>
</html>
export const CHAT_CHANNEL = "chat"
export function waitForAllICE(peerConnection) {
return waitForEvent((fulfill) => {
peerConnection.onicecandidate = (iceEvent) => {
if (iceEvent.candidate === null)
fulfill()
}
})
}
export function waitForEvent(user_function) {
return new Promise((fulfill, reject) => {
user_function(fulfill)
setTimeout(() => reject("Waited too long"), 60000)
})
}
export function addConnectionStateHandler(peerConnection) {
peerConnection.onconnectionstatechange = function () {
console.log(peerConnection.connectionState)
};
}
export function collectAllICE(peerConnection, iceCandidatesList) {
return waitForEvent((fulfill) => {
peerConnection.onicecandidate = (iceEvent) => {
if (iceEvent.candidate === null) {
fulfill()
}
else {
iceCandidatesList.push(iceEvent.candidate)
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment