forked from rtc-io/rtc-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
monitor.js
113 lines (88 loc) · 3.04 KB
/
monitor.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
/* jshint node: true */
'use strict';
var EventEmitter = require('events').EventEmitter;
// define some state mappings to simplify the events we generate
var stateMappings = {
completed: 'connected'
};
// define the events that we need to watch for peer connection
// state changes
var peerStateEvents = [
'signalingstatechange',
'iceconnectionstatechange',
];
/**
### rtc/monitor
```
monitor(pc, targetId, signaller, opts?) => EventEmitter
```
The monitor is a useful tool for determining the state of `pc` (an
`RTCPeerConnection`) instance in the context of your application. The
monitor uses both the `iceConnectionState` information of the peer
connection and also the various
[signaller events](https://github.com/rtc-io/rtc-signaller#signaller-events)
to determine when the connection has been `connected` and when it has
been `disconnected`.
A monitor created `EventEmitter` is returned as the result of a
[couple](https://github.com/rtc-io/rtc#rtccouple) between a local peer
connection and it's remote counterpart.
**/
module.exports = function(pc, targetId, signaller, opts) {
var debugLabel = (opts || {}).debugLabel || 'rtc';
var debug = require('cog/logger')(debugLabel + '/monitor');
var monitor = new EventEmitter();
var state;
function checkState() {
var newState = getMappedState(pc.iceConnectionState);
debug('state changed: ' + pc.iceConnectionState + ', mapped: ' + newState);
// flag the we had a state change
monitor.emit('change', pc);
// if the active state has changed, then send the appopriate message
if (state !== newState) {
monitor.emit(newState);
state = newState;
}
}
function handlePeerLeave(peerId) {
debug('captured peer leave for peer: ' + peerId);
// if the peer leaving is not the peer we are connected to
// then we aren't interested
if (peerId !== targetId) {
return;
}
// trigger a closed event
monitor.emit('closed');
}
pc.onclose = monitor.emit.bind(monitor, 'closed');
peerStateEvents.forEach(function(evtName) {
pc['on' + evtName] = checkState;
});
monitor.stop = function() {
pc.onclose = null;
peerStateEvents.forEach(function(evtName) {
pc['on' + evtName] = null;
});
// remove the peer:leave listener
if (signaller && typeof signaller.removeListener == 'function') {
signaller.removeListener('peer:leave', handlePeerLeave);
}
};
monitor.checkState = checkState;
// if we haven't been provided a valid peer connection, abort
if (! pc) {
return monitor;
}
// determine the initial is active state
state = getMappedState(pc.iceConnectionState);
// if we've been provided a signaller, then watch for peer:leave events
if (signaller && typeof signaller.on == 'function') {
signaller.on('peer:leave', handlePeerLeave);
}
// if we are active, trigger the connected state
// setTimeout(monitor.emit.bind(monitor, state), 0);
return monitor;
};
/* internal helpers */
function getMappedState(state) {
return stateMappings[state] || state;
}