Snowflake proxy successfully reset and bootstrap a new client (#15)

This commit is contained in:
Serene Han 2016-01-22 12:22:09 -08:00
parent 133f657928
commit 77fbfe0e66
4 changed files with 33 additions and 25 deletions

View file

@ -171,7 +171,9 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
w.Write(offer) w.Write(offer)
case <-time.After(time.Second * 10): case <-time.After(time.Second * 10):
// This snowflake is no longer available to serve clients.
heap.Remove(snowflakes, snowflake.index) heap.Remove(snowflakes, snowflake.index)
delete(snowflakeMap, snowflake.id)
w.WriteHeader(http.StatusGatewayTimeout) w.WriteHeader(http.StatusGatewayTimeout)
} }
} }

View file

@ -69,7 +69,6 @@ class Broker
return return
xhr.onreadystatechange = -> xhr.onreadystatechange = ->
return if xhr.DONE != xhr.readyState return if xhr.DONE != xhr.readyState
log xhr
switch xhr.status switch xhr.status
when STATUS_OK when STATUS_OK
log 'Broker: Successfully replied with answer.' log 'Broker: Successfully replied with answer.'

View file

@ -19,7 +19,8 @@ class ProxyPair
constructor: (@clientAddr, @relayAddr, @rateLimit) -> constructor: (@clientAddr, @relayAddr, @rateLimit) ->
connectClient: => # Prepare a WebRTC PeerConnection and await for an SDP offer.
begin: ->
@pc = new PeerConnection config, { @pc = new PeerConnection config, {
optional: [ optional: [
{ DtlsSrtpKeyAgreement: true } { DtlsSrtpKeyAgreement: true }
@ -44,6 +45,16 @@ class ProxyPair
@prepareDataChannel channel @prepareDataChannel channel
@client = channel @client = channel
receiveWebRTCOffer: (offer) ->
console.assert 'offer' == offer.type
try
err = @pc.setRemoteDescription offer
catch e
log 'Invalid SDP message.'
return false
log 'SDP ' + offer.type + ' successfully received.'
true
prepareDataChannel: (channel) => prepareDataChannel: (channel) =>
channel.onopen = => channel.onopen = =>
log 'Data channel opened!' log 'Data channel opened!'
@ -56,8 +67,9 @@ class ProxyPair
log 'Data channel closed.' log 'Data channel closed.'
snowflake.state = MODE.INIT snowflake.state = MODE.INIT
$msglog.className = '' $msglog.className = ''
channel.onerror = -> # Change this for multiplexing.
log 'Data channel error!' snowflake.reset()
channel.onerror = -> log 'Data channel error!'
channel.onmessage = @onClientToRelayMessage channel.onmessage = @onClientToRelayMessage
# Assumes WebRTC datachannel is connected. # Assumes WebRTC datachannel is connected.

View file

@ -87,21 +87,17 @@ class Snowflake
return false return false
@relayAddr = addr @relayAddr = addr
log 'Using ' + relayAddr + ' as Relay.' log 'Using ' + relayAddr + ' as Relay.'
@beginWebRTC() log 'Input offer from the snowflake client:' if COPY_PASTE_ENABLED
log 'Input offer from the snowflake client:'
return true return true
# Initialize WebRTC PeerConnection # Initialize WebRTC PeerConnection
beginWebRTC: -> beginWebRTC: ->
log 'Starting up Snowflake...\n'
@state = MODE.WEBRTC_CONNECTING @state = MODE.WEBRTC_CONNECTING
for i in [1..CONNECTIONS_PER_CLIENT] for i in [1..CONNECTIONS_PER_CLIENT]
@makeProxyPair @relayAddr @makeProxyPair @relayAddr
@proxyPair = @proxyPairs[0] @proxyPair = @proxyPairs[0]
# Poll broker for clients. # Poll broker for clients.
findClients: -> findClients = =>
poll = =>
recv = broker.getClientOffer() recv = broker.getClientOffer()
recv.then((desc) => recv.then((desc) =>
offer = JSON.parse desc offer = JSON.parse desc
@ -109,21 +105,15 @@ class Snowflake
@receiveOffer offer @receiveOffer offer
, (err) -> , (err) ->
log err log err
setTimeout(poll, 1000) setTimeout(findClients, 1000)
) )
poll() findClients()
# Receive an SDP offer from client plugin. # Receive an SDP offer from some client assigned by the Broker.
receiveOffer: (desc) => receiveOffer: (desc) =>
sdp = new RTCSessionDescription desc sdp = new RTCSessionDescription desc
try if @proxyPair.receiveWebRTCOffer sdp
err = @proxyPair.pc.setRemoteDescription sdp
catch e
log 'Invalid SDP message.'
return false
log 'SDP ' + sdp.type + ' successfully received.'
@sendAnswer() if 'offer' == sdp.type @sendAnswer() if 'offer' == sdp.type
true
sendAnswer: => sendAnswer: =>
next = (sdp) => next = (sdp) =>
@ -132,7 +122,6 @@ class Snowflake
promise = @proxyPair.pc.createAnswer next promise = @proxyPair.pc.createAnswer next
promise.then next if promise promise.then next if promise
makeProxyPair: (relay) -> makeProxyPair: (relay) ->
pair = new ProxyPair null, relay, @rateLimit pair = new ProxyPair null, relay, @rateLimit
@proxyPairs.push pair @proxyPairs.push pair
@ -141,7 +130,7 @@ class Snowflake
@proxyPairs.splice(@proxyPairs.indexOf(pair), 1) @proxyPairs.splice(@proxyPairs.indexOf(pair), 1)
@badge.endProxy() if @badge @badge.endProxy() if @badge
try try
pair.connectClient() pair.begin()
catch err catch err
log 'ERROR: ProxyPair exception while connecting.' log 'ERROR: ProxyPair exception while connecting.'
log err log err
@ -162,6 +151,12 @@ class Snowflake
@cease() @cease()
@badge.die() if @badge @badge.die() if @badge
# Close all existing ProxyPairs and begin finding new clients from scratch.
reset: ->
@cease()
log '\nSnowflake resetting...'
@beginWebRTC()
snowflake = null snowflake = null
broker = null broker = null
@ -241,6 +236,6 @@ init = ->
log 'Input desired relay address:' log 'Input desired relay address:'
else else
snowflake.setRelayAddr DEFAULT_WEBSOCKET snowflake.setRelayAddr DEFAULT_WEBSOCKET
snowflake.findClients() snowflake.beginWebRTC()
window.onload = init if window window.onload = init if window