1 document
.title
= "Strapp.io Host"
4 const conf
= {"iceServers": [{ "urls": "stun:stun.1.google.com:19302" }] }
5 const clients
= new Map([])
6 const iceCandidates
= []
10 /* TODO: duplicate in both client.js and host.jhs */
11 function getPublicKey() {
12 return new Promise( (resolve
, reject
) => {
13 /* Check local storage for public key */
14 if (!window
.localStorage
.getItem('public-key')) {
15 console
.log('public key is undefined')
16 /* If doesn't exist, generate public and private key pair, store in
18 crypto
.subtle
.generateKey(
21 publicExponent
: new Uint8Array([0x01, 0x00, 0x01]),
22 hash
: {name
: "SHA-256"}
25 ['encrypt', 'decrypt']
27 /* TODO: Do we need to store the private key as well? */
28 crypto
.subtle
.exportKey('jwk', keyPair
.publicKey
)
29 .then((exportedKey
) => {
30 window
.localStorage
.setItem('publicKey', exportedKey
)
31 console
.log('public key is' + window
.localStorage
.getItem('publicKey'))
38 resolve(window
.localStorage
.getItem('publicKey'))
43 function handleNewClientConnection(offer
) {
44 /* New Client Connection*/
45 hpc
= new RTCPeerConnection(conf
)
47 clients
.set(offer
.pubKey
, hpc
)
48 hpc
.setRemoteDescription(offer
.sdp
)
50 hpc
.createAnswer().then((answer
) => {
51 return hpc
.setLocalDescription(answer
)
54 getPublicKey().then((hpk
) => {
55 hpc
.onicecandidate
= (event
) => {
56 if (event
.candidate
) {
57 console
.log('Host: Allocating ice candidate for client')
58 iceCandidates
.push(JSON
.stringify({
61 hostPubKey
: hpk
.n
, /* TODO: do we need to send this? */
62 clientPubKey
: offer
.pubKey
,
67 console
.log('Host: Finished sending ICE candidates')
71 console
.log('Host: Sending answer to Client')
72 wsock
.send(JSON
.stringify({
74 sdp
: hpc
.localDescription
,
76 clientPubKey
: offer
.pubKey
78 hpc
.ondatachannel
= (evt
) => {
79 dataChannel
= evt
.channel
81 dataChannel
.onmessage
= (msg
) => {
84 dataChannel
.onopen
= () => {
85 dataChannel
.send(`Hi ${offer.pubKey} -host`)
88 hpc
.oniceconnectionstatechange
= () => {
89 console
.log('iceConnectionState = ' + hpc
.iceConnectionState
)
93 console
.log(`error in host answer ${err}`)
99 function handleNewIceSubmission(msg
) {
100 console
.log('Host: Adding new ice candidate')
101 const hpc
= clients
.get(msg
.pubKey
)
102 let candidate
= new RTCIceCandidate(msg
.ice
)
103 hpc
.addIceCandidate(candidate
)
106 function handleIceRequest(msg
) {
107 console
.log('Host: Handling ice candidate request')
108 console
.log(iceCandidates
)
109 const hpc
= clients
.get(msg
.pubKey
)
110 const iceCandidate
= iceCandidates
.pop()
111 if (iceCandidate
!== undefined) {
112 wsock
.send(iceCandidate
)
114 if (hpc
.iceGatheringState
.localeCompare('gathering') === 0) {
115 wsock
.send(`{"cmd" : "< ice pubKey", "clientPubKey":"${msg.pubKey}", "iceState": "g"}`)
117 else if (hpc
.iceGatheringState
.localeCompare('complete') === 0) {
118 wsock
.send(`{"cmd" : "< ice pubKey", "clientPubKey":"${msg.pubKey}", "iceState": "c"}`)
124 if ("WebSocket" in window
) {
125 document
.addEventListener('DOMContentLoaded', (event
) => {
126 wsock
= new WebSocket(`${_strapp_protocol}://${window.location.hostname}:${_strapp_port}`)
127 wsock
.onopen
= () => {
128 console
.log(`Strapped to ${_strapp_protocol}://${window.location.hostname}:${_strapp_port}`)
131 wsock
.onmessage
= (serverMsg
) => {
132 /* msg is either offer or ice candidate or ice candidate request*/
134 /* What if data null? */
135 let msg
= JSON
.parse(serverMsg
.data
)
137 const clientID
= msg
.pubKey
139 /* TODO: redo this trash */
140 if (clients
.has(clientID
)) {
142 handleNewIceSubmission(msg
)
143 } else if (msg
.sdp
) {
144 //handleRepeatedOffer
146 handleIceRequest(msg
)
151 console
.log('Host: Client that doesnt exist is sending ice submissions')
152 } else if (msg
.sdp
) {
153 handleNewClientConnection(msg
)
155 console
.log('Host: Client that doesnt exist is sending ice requests')
159 document
.body
.innerHTML
= '<div>Choose options for client</div> <video autoplay></video>'
161 navigator
.mediaDevices
.getUserMedia({ video
: { mediaSource
: "screen", // whole screen sharing
162 // mediaSource: "window", // choose a window to share
163 // mediaSource: "application", // choose a window to share
164 width
: {max
: '1920'},
165 height
: {max
: '1080'},
166 frameRate
: {max
: '10'}} })
167 .then(function(mediaStream
) {
168 let video
= document
.querySelector('video')
169 video
.srcObject
= mediaStream
170 video
.onloadedmetadata = function(e
) {
174 .catch(function(err
) { console
.log(err
); }); // always check for errors at the end.
178 document
.addEventListener('DOMContentLoaded', () => {
179 document
.body
.innerHTML
= 'Websockets not supported in your browser'