diff options
Diffstat (limited to 'lib/webtorrent.js')
-rw-r--r-- | lib/webtorrent.js | 186 |
1 files changed, 126 insertions, 60 deletions
diff --git a/lib/webtorrent.js b/lib/webtorrent.js index d0db6e066..7cd38156c 100644 --- a/lib/webtorrent.js +++ b/lib/webtorrent.js | |||
@@ -1,92 +1,158 @@ | |||
1 | ;(function () { | 1 | ;(function () { |
2 | 'use strict' | 2 | 'use strict' |
3 | 3 | ||
4 | function webtorrent (args) { | 4 | var config = require('config') |
5 | var WebTorrent = require('webtorrent') | 5 | var ipc = require('node-ipc') |
6 | var ipc = require('node-ipc') | 6 | var pathUtils = require('path') |
7 | var spawn = require('electron-spawn') | ||
8 | |||
9 | var logger = require('../helpers/logger') | ||
10 | |||
11 | var host = config.get('webserver.host') | ||
12 | var port = config.get('webserver.port') | ||
13 | var nodeKey = 'webtorrentnode' + port | ||
14 | var processKey = 'webtorrentprocess' + port | ||
15 | ipc.config.silent = true | ||
16 | ipc.config.id = nodeKey | ||
17 | |||
18 | var webtorrent = { | ||
19 | add: add, | ||
20 | app: null, // Pid of the app | ||
21 | create: create, | ||
22 | remove: remove, | ||
23 | seed: seed, | ||
24 | silent: false // Useful for beautiful tests | ||
25 | } | ||
7 | 26 | ||
8 | if (args.length !== 3) { | 27 | function create (options, callback) { |
9 | console.log('Wrong arguments number: ' + args.length + '/3') | 28 | if (typeof options === 'function') { |
10 | process.exit(-1) | 29 | callback = options |
30 | options = {} | ||
11 | } | 31 | } |
12 | 32 | ||
13 | var host = args[1] | 33 | // Override options |
14 | var port = args[2] | 34 | if (options.host) host = options.host |
15 | var nodeKey = 'webtorrentnode' + port | 35 | if (options.port) { |
16 | var processKey = 'webtorrent' + port | 36 | port = options.port |
37 | nodeKey = 'webtorrentnode' + port | ||
38 | processKey = 'webtorrentprocess' + port | ||
39 | ipc.config.id = nodeKey | ||
40 | } | ||
17 | 41 | ||
18 | ipc.config.silent = true | 42 | ipc.serve(function () { |
19 | ipc.config.id = processKey | 43 | if (!webtorrent.silent) logger.info('IPC server ready.') |
20 | 44 | ||
21 | if (host === 'client' && port === '1') global.WEBTORRENT_ANNOUNCE = [] | 45 | // Run a timeout of 30s after which we exit the process |
22 | else global.WEBTORRENT_ANNOUNCE = 'ws://' + host + ':' + port + '/tracker/socket' | 46 | var timeout_webtorrent_process = setTimeout(function () { |
23 | var wt = new WebTorrent({ dht: false }) | 47 | logger.error('Timeout : cannot run the webtorrent process. Please ensure you have electron-prebuilt npm package installed with xvfb-run.') |
48 | process.exit() | ||
49 | }, 30000) | ||
24 | 50 | ||
25 | function seed (data) { | 51 | ipc.server.on(processKey + '.ready', function () { |
26 | var args = data.args | 52 | if (!webtorrent.silent) logger.info('Webtorrent process ready.') |
27 | var path = args.path | 53 | clearTimeout(timeout_webtorrent_process) |
28 | var _id = data._id | 54 | callback() |
55 | }) | ||
29 | 56 | ||
30 | wt.seed(path, { announceList: '' }, function (torrent) { | 57 | ipc.server.on(processKey + '.exception', function (data) { |
31 | var to_send = { | 58 | logger.error('Received exception error from webtorrent process.', { exception: data.exception }) |
32 | magnetUri: torrent.magnetURI | 59 | process.exit() |
33 | } | 60 | }) |
34 | 61 | ||
35 | ipc.of[nodeKey].emit(nodeKey + '.seedDone.' + _id, to_send) | 62 | var webtorrent_process = spawn(__dirname + '/webtorrentProcess.js', host, port, { detached: true }) |
63 | webtorrent_process.stderr.on('data', function (data) { | ||
64 | // logger.debug('Webtorrent process stderr: ', data.toString()) | ||
36 | }) | 65 | }) |
37 | } | ||
38 | 66 | ||
39 | function add (data) { | 67 | webtorrent_process.stdout.on('data', function (data) { |
40 | var args = data.args | 68 | // logger.debug('Webtorrent process:', data.toString()) |
41 | var magnetUri = args.magnetUri | 69 | }) |
42 | var _id = data._id | ||
43 | 70 | ||
44 | wt.add(magnetUri, function (torrent) { | 71 | webtorrent.app = webtorrent_process |
45 | var to_send = { | 72 | }) |
46 | files: [] | ||
47 | } | ||
48 | 73 | ||
49 | torrent.files.forEach(function (file) { | 74 | ipc.server.start() |
50 | to_send.files.push({ path: file.path }) | 75 | } |
51 | }) | ||
52 | 76 | ||
53 | ipc.of[nodeKey].emit(nodeKey + '.addDone.' + _id, to_send) | 77 | function seed (path, callback) { |
54 | }) | 78 | var extension = pathUtils.extname(path) |
79 | var basename = pathUtils.basename(path, extension) | ||
80 | var data = { | ||
81 | _id: basename, | ||
82 | args: { | ||
83 | path: path | ||
84 | } | ||
55 | } | 85 | } |
56 | 86 | ||
57 | function remove (data) { | 87 | if (!webtorrent.silent) logger.debug('Node wants to seed %s.', data._id) |
58 | var args = data.args | ||
59 | var magnetUri = args.magnetUri | ||
60 | var _id = data._id | ||
61 | 88 | ||
62 | try { | 89 | // Finish signal |
63 | wt.remove(magnetUri, callback) | 90 | var event_key = nodeKey + '.seedDone.' + data._id |
64 | } catch (err) { | 91 | ipc.server.on(event_key, function listener (received) { |
65 | console.log('Cannot remove the torrent from WebTorrent.') | 92 | if (!webtorrent.silent) logger.debug('Process seeded torrent %s.', received.magnetUri) |
66 | return callback(null) | 93 | |
94 | // This is a fake object, we just use the magnetUri in this project | ||
95 | var torrent = { | ||
96 | magnetURI: received.magnetUri | ||
67 | } | 97 | } |
68 | 98 | ||
69 | function callback () { | 99 | ipc.server.off(event_key) |
70 | var to_send = {} | 100 | callback(torrent) |
71 | ipc.of[nodeKey].emit(nodeKey + '.removeDone.' + _id, to_send) | 101 | }) |
102 | |||
103 | ipc.server.broadcast(processKey + '.seed', data) | ||
104 | } | ||
105 | |||
106 | function add (magnetUri, callback) { | ||
107 | var data = { | ||
108 | _id: magnetUri, | ||
109 | args: { | ||
110 | magnetUri: magnetUri | ||
72 | } | 111 | } |
73 | } | 112 | } |
74 | 113 | ||
75 | console.log('Configuration: ' + host + ':' + port) | 114 | if (!webtorrent.silent) logger.debug('Node wants to add ' + data._id) |
76 | console.log('Connecting to IPC...') | ||
77 | 115 | ||
78 | ipc.connectTo(nodeKey, function () { | 116 | // Finish signal |
79 | ipc.of[nodeKey].on(processKey + '.seed', seed) | 117 | var event_key = nodeKey + '.addDone.' + data._id |
80 | ipc.of[nodeKey].on(processKey + '.add', add) | 118 | ipc.server.on(event_key, function (received) { |
81 | ipc.of[nodeKey].on(processKey + '.remove', remove) | 119 | if (!webtorrent.silent) logger.debug('Process added torrent.') |
120 | |||
121 | // This is a fake object, we just use the magnetUri in this project | ||
122 | var torrent = { | ||
123 | files: received.files | ||
124 | } | ||
82 | 125 | ||
83 | ipc.of[nodeKey].emit(processKey + '.ready') | 126 | ipc.server.off(event_key) |
84 | console.log('Ready.') | 127 | callback(torrent) |
85 | }) | 128 | }) |
86 | 129 | ||
87 | process.on('uncaughtException', function (e) { | 130 | ipc.server.broadcast(processKey + '.add', data) |
88 | ipc.of[nodeKey].emit(processKey + '.exception', { exception: e }) | 131 | } |
132 | |||
133 | function remove (magnetUri, callback) { | ||
134 | var data = { | ||
135 | _id: magnetUri, | ||
136 | args: { | ||
137 | magnetUri: magnetUri | ||
138 | } | ||
139 | } | ||
140 | |||
141 | if (!webtorrent.silent) logger.debug('Node wants to stop seeding %s.', data._id) | ||
142 | |||
143 | // Finish signal | ||
144 | var event_key = nodeKey + '.removeDone.' + data._id | ||
145 | ipc.server.on(event_key, function (received) { | ||
146 | if (!webtorrent.silent) logger.debug('Process removed torrent %s.', data._id) | ||
147 | |||
148 | var err = null | ||
149 | if (received.err) err = received.err | ||
150 | |||
151 | ipc.server.off(event_key) | ||
152 | callback(err) | ||
89 | }) | 153 | }) |
154 | |||
155 | ipc.server.broadcast(processKey + '.remove', data) | ||
90 | } | 156 | } |
91 | 157 | ||
92 | // --------------------------------------------------------------------------- | 158 | // --------------------------------------------------------------------------- |