const connection = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }); connection.onicecandidate = (e) => { if (e.candidate) { localStorage.setItem('candidate', JSON.stringify(e.candidate)); } }; connection.oniceconnectionstatechange = (e) => { console.log(connection.iceConnectionState); } const channel = connection.createDataChannel('chat', { negociated: true, id: 'very secret' }); channel.onmessage = ({ data }) => console.log(data); window.sendMessage = (message) => { channel.send(message) } async function createOffer() { const offer = await connection.createOffer(); connection.setLocalDescription(offer) localStorage.setItem('offer', JSON.stringify(offer)); } async function createAnswer(offer) { connection.setRemoteDescription( new RTCSessionDescription(offer) ); const answer = await connection.createAnswer(); connection.setLocalDescription(answer) localStorage.setItem('answer', JSON.stringify(answer)) } async function acceptAnswer(answer) { connection.setRemoteDescription(new RTCSessionDescription(answer)); }; window.addEventListener('storage', ({ key, newValue }) => { switch(key) { case 'offer': createAnswer(JSON.parse(newValue)); break; case 'answer': acceptAnswer(JSON.parse(newValue)); break; case 'candidate': connection.addIceCandidate(JSON.parse(newValue)); break; } });