-
Notifications
You must be signed in to change notification settings - Fork 12
/
app.js
160 lines (151 loc) · 4.6 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
require([
'modules/peer', 'modules/transport', 'modules/layout', 'backbone', 'q'
], function(Peer, Transport, Layout, Backbone, Q) {
'use strict';
var config = {
socketServer: 'ws://' + window.location.host,
pcConfig: {
iceServers: [
{ url: 'stun:stun.l.google.com:19302' },
{ url: 'stun:23.21.150.121' }
]
}
};
// TODO: Fetch contacts from remote identitiy provider
var contacts = [
{ name: 'creationix' },
{ name: 'robin' },
{ name: 'erik' },
{ name: 'lawrence' },
{ name: 'cassie' },
{ name: 'jugglinmike' }
];
var mediaConstraints = {
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
}
};
function createOfferFailed() {
console.error('Create Answer failed');
}
function createAnswerFailed() {
console.error('Create Answer failed');
}
var user = new Peer();
var pc = new Peer();
var layout = new Layout({
el: '#app',
user: user,
contacts: new Backbone.Collection(contacts)
});
layout.render();
layout.on('connectRequest', function(stream) {
// TODO: Derive remote peer ID from application state
var remotePeerID = 'creationix';
if (!pc.isActive() && transport.state === 'OPEN') {
pc.connect(config.pcConfig);
pc.addStream(stream);
pc.createOffer(
function(sessionDescription) {
this.setLocalDescription(sessionDescription);
transport.peerLocationFind(remotePeerID, {
session: sessionDescription,
userName: user.get('name')
}).then(function(findReply) {
console.log('Promise Resolved', findReply);
pc.setRemoteDescription(findReply.sessionDescription);
pc.set('locationID', findReply.from);
}, function() {
// TODO: Update the UI to reflect this failure.
console.error('Find request failed.');
});
},
createOfferFailed,
mediaConstraints);
}
});
layout.on('hangup', function() {
transport.request('bye', {
to: pc.get('locationID')
});
pc.destroy();
});
pc.on('addstream', function(stream) {
console.log('Remote stream added');
layout.playRemoteStream(stream);
});
pc.on('removestream', function() {
console.log('Remove remote stream');
layout.stopRemoteStream();
});
pc.on('ice', function(candidate) {
console.log('Sending ICE candidate:', candidate);
transport.request('update', {
candidate: candidate,
to: pc.get('locationID')
});
});
var transport = new Transport({
invite: function(request) {
var blob = request && request.username && request.username.blob;
var remoteSession;
if (!blob) {
console.error('No blob found. Ignoring invite.');
return;
}
remoteSession = blob.session;
if (!remoteSession) {
console.error('Remote session not specified. Ignoring invite.');
return;
}
// TODO: Prompt user to accept/reject call (instead of blindly accepting)
// and move following logic into "Accept" handler.
console.log('Receiving call from ' + blob.userName +
'. Would you like to answer?');
if (!pc.isActive()) {
pc.connect(config.pcConfig);
// TODO: Refactor so transport is not so tightly-coupled to the layout.
// This should also allow recieving calls without sharing the local
// stream.
pc.addStream(layout.localStreamView.getStream());
}
pc.set('locationID', request.username.from);
console.log('Creating remote session description:', remoteSession);
pc.setRemoteDescription(remoteSession);
console.log('Sending answer...');
var dfd = Q.defer();
pc.createAnswer(function(sessionDescription) {
this.setLocalDescription(sessionDescription);
dfd.resolve({
peer: true,
sessionDescription: sessionDescription
});
},
createAnswerFailed, mediaConstraints);
return dfd.promise;
},
bye: function() {
pc.destroy();
},
update: function(msg) {
if (!pc.isActive()) {
return;
}
console.log('Received ICE candidate:', msg.candidate);
pc.addIceCandidate(msg.candidate);
}
});
user.on('change:name', function() {
transport.open(new WebSocket(config.socketServer))
.then(function() {
return transport.sessionCreate(user.get('name'));
})
.then(function() {
// Simulate network latency
setTimeout(function() {
layout.login();
}, 800);
}, console.error.bind(console));
});
});