-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtracker.js
More file actions
93 lines (80 loc) · 2.31 KB
/
tracker.js
File metadata and controls
93 lines (80 loc) · 2.31 KB
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
const RPC = require('./rpc')
module.exports = class Tracker extends RPC {
constructor(options = {}) {
options.discoverable = false
super(options)
}
bindEventListeners() {
super.bindEventListeners()
this.environment.on('module', module => this.handleModule(module))
}
handleReady() {
super.handleReady()
this.network.connect({
id: 'tracker',
transport: {
accepts: ['websocket'],
websocket: { url: 'tracker' },
},
})
}
async handleModule(module) {
const description = this.getDescription(module)
if (module.discoverable) {
this.remotes.forEach(tracker => tracker.add(description))
}
this.remotes.forEach(tracker => this.discover(description, tracker))
}
handleRemote(tracker) {
super.handleRemote(tracker)
const { modulesByLabel } = this.environment
Object.keys(modulesByLabel).forEach(label => {
modulesByLabel[label].forEach(module => {
const description = this.getDescription(module)
if (module.discoverable) tracker.add(description)
this.discover(description, tracker)
})
})
}
handleIncomingConnection() {}
handleOutgoingConnection(connection) {
if (connection.peer !== 'tracker') return
super.handleOutgoingConnection(connection)
}
getDescription(module) {
return {
node: this.getNodeDescription(),
module: this.getModuleDescription(module),
}
}
getNodeDescription() {
const { id } = this.network
const { accepts } = this.network.transport
const transport = { accepts }
return { id, transport }
}
getModuleDescription(module) {
const label = module.label
const streamName = module.streamName
return { label, streamName }
}
async discover(query, tracker) {
const { streamName } = query.module
const selector = { 'module.streamName': streamName }
const available = await tracker.query(selector)
available.forEach(description => {
if (description.node.id === this.network.id) return
this.network.connect(description.node)
})
}
offer(description) {
const { node } = description
setTimeout(() => {
this.network.connect(node)
}, 10 * 1000)
}
getProtocol(methods = {}) {
methods.offer = (...args) => this.offer(...args)
return super.getProtocol(methods)
}
}