Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/webtorrent/webtorrent.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFeross Aboukhadijeh <feross@feross.org>2016-04-21 09:10:32 +0300
committerFeross Aboukhadijeh <feross@feross.org>2016-04-21 09:10:32 +0300
commit3daee2c66cbf752b9e6e49b99492b8c1914a4a58 (patch)
treefbdd6c10f6a64674268dc77d1b3ccb4a37c44a65 /index.js
parent7a7c4a8b8c49f5c92b7c20ff439bc8614f7d607e (diff)
BREAKING: Major cleanup
### Added - `client.listening` property to signal whether TCP server is listening for incoming connections. ### Changed - Merged `Swarm` class into `Torrent` object. Properties on `torrent.swarm` (like `torrent.swarm.wires`) now exist on `torrent` (e.g. `torrent.wires`). - `torrent.addPeer` can no longer be called before the `infoHash` event has been emitted. - Remove `torrent.on('listening')` event. Use `client.on('listening')` instead. - Remove support from `TCPPool` for listening on multiple ports. This was not used by WebTorrent and just added complexity. There is now a single `TCPPool` instance for the whole WebTorrent client. - Deprecate: Do not use `client.download()` anymore. Use `client.add()` instead. - Deprecate: Do not use `torrent.swarm` anymore. Use `torrent` instead. ### Fixed - When there is a `torrent.on('error')` listener, don't also emit `client.on('error')`. - Do not return existing torrent object when duplicate torrent is added. Fire an `'error'` event instead. - Memory leak of `Torrent` object caused by `RarityMap` - Memory leak of `Torrent` object caused by `TCPPool` - `client.ratio` and `torrent.ratio` are now calculated as `uploaded / received` instead of `uploaded / downloaded`.
Diffstat (limited to 'index.js')
-rw-r--r--index.js130
1 files changed, 80 insertions, 50 deletions
diff --git a/index.js b/index.js
index 59be529..dc6bedf 100644
--- a/index.js
+++ b/index.js
@@ -1,3 +1,6 @@
+// TODO: cleanup event listeners
+// TODO: set dhtPort to correct port
+
module.exports = WebTorrent
var createTorrent = require('create-torrent')
@@ -16,10 +19,9 @@ var speedometer = require('speedometer')
var zeroFill = require('zero-fill')
var concatStream = require('./lib/concat-stream')
+var TCPPool = require('./lib/tcp-pool') // browser exclude
var Torrent = require('./lib/torrent')
-module.exports.WEBRTC_SUPPORT = Peer.WEBRTC_SUPPORT
-
/**
* WebTorrent version.
*/
@@ -55,36 +57,44 @@ function WebTorrent (opts) {
if (!opts) opts = {}
+ self.peerId = typeof opts.peerId === 'string'
+ ? opts.peerId
+ : (opts.peerId || new Buffer(VERSION_PREFIX + hat(48))).toString('hex')
+ self.peerIdBuffer = new Buffer(self.peerId, 'hex')
+
+ self.nodeId = typeof opts.nodeId === 'string'
+ ? opts.nodeId
+ : (opts.nodeId && opts.nodeId.toString('hex')) || hat(160)
+ self.nodeIdBuffer = new Buffer(self.nodeId, 'hex')
+
self.destroyed = false
+ self.listening = false
self.torrentPort = opts.torrentPort || 0
self.tracker = opts.tracker !== undefined ? opts.tracker : true
+ self.torrents = []
+ self.maxConns = Number(opts.maxConns) || 55
self._rtcConfig = opts.rtcConfig
self._wrtc = opts.wrtc || global.WRTC // to support `webtorrent-hybrid` package
- self.torrents = []
+ if (typeof TCPPool === 'function') {
+ self._tcpPool = new TCPPool(self)
+ } else {
+ process.nextTick(function () {
+ self._onListening()
+ })
+ }
+ // stats
self._downloadSpeed = speedometer()
self._uploadSpeed = speedometer()
- self.maxConns = opts.maxConns
-
- self.peerId = typeof opts.peerId === 'string'
- ? opts.peerId
- : (opts.peerId || new Buffer(VERSION_PREFIX + hat(48))).toString('hex')
- self.peerIdBuffer = new Buffer(self.peerId, 'hex')
-
- self.nodeId = typeof opts.nodeId === 'string'
- ? opts.nodeId
- : (opts.nodeId && opts.nodeId.toString('hex')) || hat(160)
- self.nodeIdBuffer = new Buffer(self.nodeId, 'hex')
-
if (opts.dht !== false && typeof DHT === 'function' /* browser exclude */) {
// use a single DHT instance for all torrents, so the routing table can be reused
self.dht = new DHT(extend({ nodeId: self.nodeId }, opts.dht))
self.dht.once('error', function (err) {
self.emit('error', err)
- self.destroy()
+ self._destroy()
})
// Ignore warning when there are > 10 torrents in the client
@@ -114,6 +124,8 @@ function WebTorrent (opts) {
}
}
+WebTorrent.WEBRTC_SUPPORT = Peer.WEBRTC_SUPPORT
+
Object.defineProperty(WebTorrent.prototype, 'downloadSpeed', {
get: function () { return this._downloadSpeed() }
})
@@ -142,10 +154,10 @@ Object.defineProperty(WebTorrent.prototype, 'ratio', {
var uploaded = this.torrents.reduce(function (total, torrent) {
return total + torrent.uploaded
}, 0)
- var downloaded = this.torrents.reduce(function (total, torrent) {
- return total + torrent.downloaded
+ var received = this.torrents.reduce(function (total, torrent) {
+ return total + torrent.received
}, 0) || 1
- return uploaded / downloaded
+ return uploaded / received
}
})
@@ -174,14 +186,18 @@ WebTorrent.prototype.get = function (torrentId) {
return null
}
+WebTorrent.prototype.download = function (torrentId, opts, ontorrent) {
+ console.warn('WebTorrent: client.download() is deprecated. Use client.add() instead')
+ return this.add(torrentId, opts, ontorrent)
+}
+
/**
* Start downloading a new torrent. Aliased as `client.download`.
* @param {string|Buffer|Object} torrentId
* @param {Object} opts torrent-specific options
* @param {function=} ontorrent called when the torrent is ready (has metadata)
*/
-WebTorrent.prototype.add =
-WebTorrent.prototype.download = function (torrentId, opts, ontorrent) {
+WebTorrent.prototype.add = function (torrentId, opts, ontorrent) {
var self = this
if (self.destroyed) throw new Error('client is destroyed')
if (typeof opts === 'function') return self.add(torrentId, null, opts)
@@ -189,29 +205,12 @@ WebTorrent.prototype.download = function (torrentId, opts, ontorrent) {
debug('add')
opts = opts ? extend(opts) : {}
- var torrent = self.get(torrentId)
-
- if (torrent) {
- if (torrent.ready) process.nextTick(onReady)
- else torrent.once('ready', onReady)
- } else {
- torrent = new Torrent(torrentId, self, opts)
- self.torrents.push(torrent)
+ var torrent = new Torrent(torrentId, self, opts)
+ self.torrents.push(torrent)
- torrent.once('error', function (err) {
- self.emit('error', err, torrent)
- self.remove(torrent)
- })
-
- torrent.once('listening', function (port) {
- self.emit('listening', port, torrent)
- })
-
- torrent.once('ready', onReady)
- }
+ torrent.once('ready', onReady)
function onReady () {
- debug('on torrent')
if (typeof ontorrent === 'function') ontorrent(torrent)
self.emit('torrent', torrent)
}
@@ -303,19 +302,20 @@ WebTorrent.prototype.seed = function (input, opts, onseed) {
* @param {function} cb
*/
WebTorrent.prototype.remove = function (torrentId, cb) {
- var self = this
debug('remove')
- var torrent = self.get(torrentId)
+ var torrent = this.get(torrentId)
if (!torrent) throw new Error('No torrent with id ' + torrentId)
- self.torrents.splice(self.torrents.indexOf(torrent), 1)
+ this.torrents.splice(this.torrents.indexOf(torrent), 1)
torrent.destroy(cb)
}
WebTorrent.prototype.address = function () {
- var self = this
- return { address: '0.0.0.0', family: 'IPv4', port: self.torrentPort }
+ if (!this.listening) return null
+ return this._tcpPool
+ ? this._tcpPool.server.address()
+ : { address: '0.0.0.0', family: 'IPv4', port: 0 }
}
/**
@@ -323,18 +323,48 @@ WebTorrent.prototype.address = function () {
* @param {function} cb
*/
WebTorrent.prototype.destroy = function (cb) {
+ if (this.destroyed) throw new Error('client already destroyed')
+ this._destroy(null, cb)
+}
+
+WebTorrent.prototype._destroy = function (err, cb) {
var self = this
- if (self.destroyed) throw new Error('client already destroyed')
+ debug('client destroy')
self.destroyed = true
- debug('destroy')
var tasks = self.torrents.map(function (torrent) {
- return function (cb) { self.remove(torrent, cb) }
+ return function (cb) {
+ torrent.destroy(cb)
+ }
})
- if (self.dht) tasks.push(function (cb) { self.dht.destroy(cb) })
+ if (self._tcpPool) {
+ tasks.push(function (cb) {
+ self._tcpPool.destroy(cb)
+ })
+ }
+
+ if (self.dht) {
+ tasks.push(function (cb) {
+ self.dht.destroy(cb)
+ })
+ }
parallel(tasks, cb)
+
+ if (err) self.emit('error', err)
+}
+
+WebTorrent.prototype._onListening = function () {
+ this.listening = true
+
+ if (this._tcpPool) {
+ // Sometimes server.address() returns `null` in Docker.
+ // WebTorrent issue: https://github.com/feross/bittorrent-swarm/pull/18
+ this.torrentPort = (this._tcpPool.server.address() || { port: 0 }).port
+ }
+
+ this.emit('listening')
}
/**