X-Git-Url: https://git.kengrimes.com/?p=henge%2Fkiak.git;a=blobdiff_plain;f=host.js;h=34d7c9deff38c6a38a32cc9b2a0c6a4ce257d33e;hp=dd48d106ae347317d4db7b8ebebe537eed8edfde;hb=b5c8f98ab42b8e7128441e4a456dfd4fc02f0e86;hpb=d33866cf8b1a188ad9ab23a934986bfd1b4726cb diff --git a/host.js b/host.js index dd48d10..34d7c9d 100644 --- a/host.js +++ b/host.js @@ -1,40 +1,123 @@ document.title = "Strapp.io Host" -const clients = [] //TODO: Change to Map -if ("WebSocket" in window) { - document.addEventListener('DOMContentLoaded', (event) => { - const wsock = new WebSocket(`${_strapp_protocol}://${window.location.hostname}:${_strapp_port}`) - wsock.onopen = () => { - console.log(`Strapped to ${_strapp_protocol}://${window.location.hostname}:${_strapp_port}`) +const conf = {"iceServers": [{ "url": "stun:stun.1.google.com:19302" }] } +const clients = new Map([]) +const hpk = getPublicKey() + +/* TODO: duplicate in both client.js and host.jhs */ +function getPublicKey() { + return new Promise( (resolve, reject) => { + /* Check local storage for public key */ + if (!window.localStorage.getItem('public-key')) { + console.log('public key is undefined') + /* If doesn't exist, generate public and private key pair, store in + local storage */ + crypto.subtle.generateKey( + { name:'RSA-OAEP', + modulusLength: 2048, + publicExponent: new Uint8Array([0x01, 0x00, 0x01]), + hash: {name: "SHA-256"} + }, + true, + ['encrypt', 'decrypt'] + ).then((keyPair) => { + /* TODO: Do we need to store the private key as well? */ + crypto.subtle.exportKey('jwk', keyPair.publicKey) + .then((exportedKey) => { + window.localStorage.setItem('publicKey', exportedKey) + console.log('public key is' + window.localStorage.getItem('publicKey')) + resolve(exportedKey) + }) + }) + } + else { + resolve(window.localStorage.getItem('publicKey')) } - wsock.onmessage = (msg) => { - /* Message is offer from client */ - /* TODO: Determine which client ?? */ - console.log("Incoming connection " + msg) - - /* TODO: State machine to parse offer */ - - /* New Client Connection*/ - hpc = new RTCPeerConnection() - - hpc.createAnswer().then((offer) => { - return hpc.setLocalDescription(offer) - }).then(() => { - return hpc.setRemoteDescription(msg.sdp) - }).then(() => { - const hpk = getPublicKey() - wsock.send({ + }) +} + + +function handleNewClientConnection(offer) { + /* New Client Connection*/ + hpc = new RTCPeerConnection(conf) + hpc.setRemoteDescription(offer.sdp) + .then(() => { + hpc.createAnswer().then((answer) => { + return hpc.setLocalDescription(answer) + }) + .then(() => { + hpk.then(() => { + hpc.onicecandidate = (event) => { + if (event.candidate) { + console.log('Host: Sending ice candidate to client') + wsock.send(JSON.stringify({ + cmd: '< ice pubKey', + ice: event.candidate, + pubKey: hpk /* TODO: do we need to send this? */ + })) + } + else { + console.log('Host: Finished setting up ICE candidates') + } + } + console.log('Host: Sending answer to Host') + wsock.send(JSON.stringify({ cmd: '< sdp pubKey', sdp: hpc.localDescription, pubKey: hpk - }) - clients.push({ + })) + clients.set(offer.pubKey, { hostsdp: hpc.localDescription, - clientsdp: hpc.remoteDescription, - clientPubKey: msg.pubKey + clientsdp: hpc.remoteDescription }) }) + }).catch((err) => { + console.log(`error in host answer ${err}`) + }) + }) +} + +function handleNewIceCandidate(msg) { + const hpc = clients.get(msg.pubKey) + let candidate = new RTCIceCandidate(msg.ice) + hpc.addIceCandidate(candidate) +} + +if ("WebSocket" in window) { + document.addEventListener('DOMContentLoaded', (event) => { + wsock = new WebSocket(`${_strapp_protocol}://${window.location.hostname}:${_strapp_port}`) + wsock.onopen = () => { + console.log(`Strapped to ${_strapp_protocol}://${window.location.hostname}:${_strapp_port}`) + } + + wsock.onmessage = (serverMsg) => { + /* msg is either offer or ice candidate */ + console.log(serverMsg.data) + let msg = JSON.parse(serverMsg.data) + + const clientID = msg.pubKey + const msgType = msg.hasOwnProperty('sdp') ? 'o' : 'i' + if (clients.has(clientID)) { + switch(msgType) { + case 'o': + console.log('client exist && sending an offer == error') + break + case 'i': + handleNewIceCandidate(msg) + break + } + } + else { + switch(msgType) { + case 'o': + handleNewClientConnection(msg) + break + case 'i': + console.log('client !exist && ice candidate === error') + break + } + } } }) } @@ -43,18 +126,3 @@ else { document.body.innerHTML = 'Websockets not supported in your browser' }) } -/* TODO: duplicate in both client.js and host.jhs */ -function getPublicKey() { - /* Check local storage for public key */ - if (window.localStorage.getItem('public-key') === undefined) { - /* If doesn't exist, generate public and private key pair, store in - local storage */ - crypto.subtle.generateKey({name:'RSA-OAEP', length: 192}, true, ['encrypt', 'decrypt']) - .then((keyPair) => { - /* TODO: Do we need to store the private key as well? */ - window.localStorage.setItem('public-key', keyPair.type.public.toString()) - }) - } - console.log(window.localStorage.getItem('public-key')) - return window.localStorage.getItem('public-key') -}