112:f4a4878c99a3
Anton Shestakov <av6@dwimlabs.net>, Thu, 07 Apr 2016 22:56:16 +0800
index: check if roster has the item before removing it Sometimes we get events from contacts that are not in user's roster, trying to remove such contacts used to fail before this patch.

next change 134:46bc2e4d7a20
previous change 60:bbab4c40a2ba

coffee/webrtc.coffee

Permissions: -rw-r--r--

Other formats: Feeds:
class Tram.WebRTCInterface
lstream: null
rstream: null
constructor: (@contact) ->
@peerJid = @contact.get('jid')
init: (@initiator, constraints) ->
if constraints.audio || constraints.video
navigator.getUserMedia(constraints, @connect, @fail)
else
@connect()
connect: (stream) =>
@call = calls.add(jid: @peerJid)
@pc = new RTCPeerConnection(iceServers: Tram.config.iceServers)
if stream?
@lstream = stream
@pc.addStream(stream)
@call.set('local/stream', stream)
@pc.onicecandidate = (event) =>
if event.candidate
@sendPayload(event.candidate, 'ice')
@pc.onaddstream = (event) =>
@rstream = event.stream
@call.set('remote/stream', event.stream)
@contact.set('callstate', 'established')
if @initiator
@sendIntent('initiate')
else
@createOffer()
onPayload: (stanza) ->
if not @call?
return
el = stanza.getElementsByTagName('payload')[0]
signal = JSON.parse(el.firstChild.nodeValue)
if signal.sdp
if signal.type is 'offer'
@receiveOffer(signal)
else if signal.type is 'answer'
@receiveAnswer(signal)
else if signal.candidate
@pc.addIceCandidate(new RTCIceCandidate(signal))
sendPayload: (data, type) ->
payload = JSON.stringify(data)
msg = $msg(to: @peerJid, type: 'chat')
.c('payload', xmlns: Tram.NS.WEBRTC, type: type).t(payload)
X.conn.send(msg.tree())
sendIntent: (intent) ->
msg = $msg(to: @peerJid, type: 'chat')
.c('intent', xmlns: Tram.NS.WEBRTC).t(intent)
X.conn.send(msg.tree())
createOffer: ->
@pc.createOffer((offer) =>
@pc.setLocalDescription(offer, =>
@sendPayload(@pc.localDescription, 'offer')
, @fail)
, @fail)
receiveOffer: (offer) ->
@pc.setRemoteDescription(new RTCSessionDescription(offer), =>
@pc.createAnswer((answer) =>
@pc.setLocalDescription(answer, =>
@sendPayload(@pc.localDescription, 'answer')
, @fail)
, @fail)
, @fail)
receiveAnswer: (answer) ->
@pc.setRemoteDescription(new RTCSessionDescription(answer))
fail: =>
@disconnect()
@contact.unset('callstate')
disconnect: ->
if @call?
@call.unset('remote/stream')
@call.unset('local/stream')
calls.remove(@call)
if @rstream?
@stopStream(@rstream)
#@pc?.removeStream?(@rstream)
if @lstream?
@stopStream(@lstream)
#@pc?.removeStream?(@lstream)
if @pc?
@pc.close()
@pc = null
stopStream: (stream) ->
if stream.getAudioTracks?
for track in stream.getAudioTracks()
track.stop?()
if stream.getVideoTracks?
for track in stream.getVideoTracks()
track.stop?()
stream.stop?()