const allRPCs = {} // https://stackoverflow.com/a/2117523 function uuidv4() { return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ) } addEventListener('rpc-needed', ({detail}) => { const {kind, target} = detail.value const isInitiatedLocally = !detail.source const uid = detail.value.uid || uuidv4() const rpc = new RTCPeerConnection(rpcConfig) rpc.onicecandidate = ({candidate}) => { if(candidate && candidate.candidate) { const cand = JSON.parse(JSON.stringify(candidate)) wire({kind: 'ice-candidate', value: {...cand, uid}, target}) } } rpc.ontrack = ({streams: [stream]}) => { stream.getTracks().forEach(track => allRPCs[uid].receiver.addTrack(track, stream) ) } rpc.oniceconnectionstatechange = (e) => { console.log(rpc.iceConnectionState) } rpc.onnegotiationneeded = (e) => { // if(isInitiatedLocally) { // signal({kind: 'rpc-initiate', value: {uid}}) // } } allRPCs[uid] = {kind, target, rpc, isInitiatedLocally} signal({kind: 'rpc-new', value: {kind, target, uid}}) if(isInitiatedLocally) { wire({kind: 'rpc-needed', value: {kind, target: State.username, uid}, target}) } }) addEventListener('rpc-setup', async ({detail}) => { const {uid, sender, receiver} = detail.value allRPCs[uid].sender = sender allRPCs[uid].receiver = receiver if(sender) { sender.getTracks().forEach(tr => allRPCs[uid].rpc.addTrack(tr, sender)) } if(allRPCs[uid].isInitiatedLocally) { signal({kind: 'rpc-initiate', value: {uid}}) } }) addEventListener('rpc-initiate', async({detail}) => { const {uid} = detail.value const {rpc, target} = allRPCs[uid] const localOffer = await rpc.createOffer() await rpc.setLocalDescription(localOffer) wire({kind: 'rpc-offer', value: {...localOffer, uid}, target}) }) addEventListener('rpc-offer', async ({detail}) => { const {uid} = detail.value const {rpc, target} = allRPCs[uid] await rpc.setRemoteDescription(detail.value) const localAnswer = await rpc.createAnswer() await rpc.setLocalDescription(localAnswer) wire({kind: 'rpc-answer', value: {...localAnswer, uid}, target}) }) addEventListener('rpc-answer', async ({detail}) => { const {uid} = detail.value await allRPCs[uid].rpc.setRemoteDescription(detail.value) }) addEventListener('ice-candidate', async ({detail}) => { const {uid} = detail.value await allRPCs[uid].rpc.addIceCandidate(detail.value) }) addEventListener('load', () => { doNotLog.add('rpc-needed') doNotLog.add('rpc-offer') doNotLog.add('rpc-answer') doNotLog.add('ice-candidate') })