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 */
- console.log("Incoming connection " + msg)
-
- /* 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({
- cmd: '< sdp pubKey'
- sdp: hpc.localDescription
+ })
+}
+
+
+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.set(offer.pubKey, {
+ hostsdp: hpc.localDescription,
+ clientsdp: hpc.remoteDescription
})
- clients.push({
- sdp: hpc.localDescription
- clientPubKey: msg.pubKey
- })
+
})
+ }).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
+ }
+ }
}
})
}