need to do ICE step
[henge/kiak.git] / host.js
diff --git a/host.js b/host.js
index dd48d10..34d7c9d 100644 (file)
--- a/host.js
+++ b/host.js
 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')
-}