Refactor Host Session

This commit is contained in:
Corey Johnson & Matt Colyer
2013-07-23 16:27:08 -07:00
parent 12ffff9dde
commit 77acaf0a1a
4 changed files with 56 additions and 91 deletions

View File

@@ -32,7 +32,7 @@ class GuestSession
guest = doc.get('collaborationState.guest')
host = doc.get('collaborationState.host')
@mediaConnection = new MediaConnection(guest, host)
@mediaConnection = new MediaConnection(guest, host, isHost: false)
waitForStream: (callback) ->
@mediaConnection.waitForStream callback

View File

@@ -4,48 +4,23 @@ _ = require 'underscore'
patrick = require 'patrick'
telepath = require 'telepath'
MediaConnection = require './media-connection'
sessionUtils = require './session-utils'
module.exports =
class HostSession
_.extend @prototype, require('event-emitter')
doc: null
participants: null
peer: null
mediaConnection: null
doc: null
sharing: false
stream: null
start: ->
return if @peer?
mediaConnection = null
constraints = {video: true, audio: true}
success = (stream) =>
mediaConnection = new webkitRTCPeerConnection(sessionUtils.getIceServers())
mediaConnection.onicecandidate = (event) =>
return unless event.candidate?
console.log "Set Host Candidate", event.candidate
@doc.set 'collaborationState.host.candidate', event.candidate
mediaConnection.onaddstream = ({@stream}) =>
@trigger 'stream-ready', @stream
console.log('Added Guest\'s Stream', @stream)
mediaConnection.addStream(stream)
navigator.webkitGetUserMedia constraints, success, console.error
@peer = sessionUtils.createPeer()
@doc = site.createDocument({})
@doc.set('windowState', atom.windowState)
patrick.snapshot project.getPath(), (error, repoSnapshot) =>
if error?
console.error(error)
return
# FIXME: There be dragons here
@doc.set 'collaborationState',
constructor: ->
@doc = site.createDocument
windowState: atom.windowState
collaborationState:
guest: {description: '', candidate: '', ready: false}
host: {description: '', candidate: ''}
participants: []
@@ -53,64 +28,50 @@ class HostSession
url: git.getConfigValue('remote.origin.url')
branch: git.getShortHead()
host = @doc.get 'collaborationState.host'
guest = @doc.get 'collaborationState.guest'
guest.on 'changed', ({key, newValue}) =>
switch key
when 'ready'
success = (description) =>
console.log "Create Offer", description
mediaConnection.setLocalDescription(description)
host.set 'description', description
host = @doc.get('collaborationState.host')
guest = @doc.get('collaborationState.guest')
@mediaConnection = new MediaConnection(host, guest, isHost: true)
mediaConnection.createOffer success, console.error
when 'description'
guestDescription = newValue.toObject()
console.log "Received Guest description", guestDescription
sessionDescription = new RTCSessionDescription(guestDescription)
mediaConnection.setRemoteDescription(sessionDescription)
when 'candidate'
guestCandidate = new RTCIceCandidate newValue.toObject()
console.log('Host received candidate', guestCandidate)
mediaConnection.addIceCandidate(new RTCIceCandidate(guestCandidate))
else
throw new Error("Unknown guest key '#{key}'")
@peer = sessionUtils.createPeer()
start: ->
return if @isSharing()
patrick.snapshot project.getPath(), (error, repoSnapshot) =>
throw new Error(error) if error
@participants = @doc.get('collaborationState.participants')
@participants.push
id: @getId()
email: git.getConfigValue('user.email')
@participants.on 'changed', =>
@trigger 'participants-changed', @participants.toObject()
@peer.on 'open', =>
@sharing = true
@trigger 'started'
@peer.on 'close', =>
@sharing = false
@trigger 'stopped'
@peer.on 'connection', (connection) =>
connection.on 'open', =>
console.log 'sending document'
@sharing = true
connection.send({repoSnapshot, doc: @doc.serialize()})
sessionUtils.connectDocument(@doc, connection)
@trigger 'started'
connection.on 'close', =>
console.log 'sharing session stopped'
@sharing = false
@participants.each (participant, index) =>
if connection.peer is participant.get('id')
@participants.remove(index)
@trigger 'stopped'
@getId()
stop: ->
return unless @peer?
@peer.destroy()
@peer = null
waitForStream: (callback) ->
@mediaConnection.waitForStream callback
getId: ->
@peer.id

View File

@@ -29,17 +29,11 @@ class HostView extends View
@hostSession.on 'participants-changed', (participants) =>
@updateParticipants(participants)
@addStream(@hostSession.stream)
@hostSession.on 'stream-ready', (stream) =>
console.log "Stream is ready", stream
@addStream(stream)
@hostSession.waitForStream (stream) =>
@video[0].src = URL.createObjectURL(stream)
@attach()
addStream: (stream) ->
return unless stream
@video[0].src = URL.createObjectURL(stream)
updateParticipants: (participants) ->
@participants.empty()
hostId = @hostSession.getId()

View File

@@ -6,12 +6,13 @@ module.exports =
class MediaConnection
_.extend @prototype, require('event-emitter')
guest: null
host: null
local: null
remote: null
connection: null
stream: null
isHost: null
constructor: (@guest, @host) ->
constructor: (@local, @remote, {@isHost}={}) ->
constraints = {video: true, audio: true}
navigator.webkitGetUserMedia constraints, @onUserMediaAvailable, @onUserMediaUnavailable
@@ -27,31 +28,40 @@ class MediaConnection
onUserMediaAvailable: (stream) =>
@connection = new webkitRTCPeerConnection(sessionUtils.getIceServers())
@connection.addStream(stream)
@host.on 'changed', @onHostSignal
@remote.on 'changed', @onRemoteSignal
@connection.onicecandidate = (event) =>
return unless event.candidate?
@guest.set 'candidate', event.candidate
@local.set 'candidate', event.candidate
@connection.onaddstream = (event) =>
@stream = event.stream
@trigger 'stream-ready', @stream
@guest.set 'ready', true
@local.set 'ready', true unless @isHost
onHostSignal: ({key, newValue}) =>
onRemoteSignal: ({key, newValue}) =>
switch key
when 'description'
hostDescription = newValue.toObject()
sessionDescription = new RTCSessionDescription(hostDescription)
@connection.setRemoteDescription(sessionDescription)
success = (guestDescription) =>
@connection.setLocalDescription(guestDescription)
@guest.set('description', guestDescription)
when 'ready'
success = (description) =>
@connection.setLocalDescription(description)
@local.set 'description', description
@connection.createOffer success, console.error
when 'description'
remoteDescription = newValue.toObject()
sessionDescription = new RTCSessionDescription(remoteDescription)
@connection.setRemoteDescription(sessionDescription)
if not @isHost
success = (localDescription) =>
@connection.setLocalDescription(localDescription)
@local.set('description', localDescription)
@connection.createAnswer success, console.error
@connection.createAnswer success, console.error
when 'candidate'
hostCandidate = new RTCIceCandidate newValue.toObject()
@connection.addIceCandidate(hostCandidate)
remoteCandidate = new RTCIceCandidate newValue.toObject()
@connection.addIceCandidate(remoteCandidate)
else
throw new Error("Unknown host key '#{key}'")
throw new Error("Unknown remote key '#{key}'")