diff options
author | Feross Aboukhadijeh <feross@feross.org> | 2014-02-01 06:58:39 +0400 |
---|---|---|
committer | Feross Aboukhadijeh <feross@feross.org> | 2014-02-01 06:58:39 +0400 |
commit | 6fa27b9f38f7fd200a739c8b400821fef34eab54 (patch) | |
tree | aa90ee40a0f1bed535ce7681552092225e793b89 | |
parent | 63cee64e8d5985cbf410cc7ce10a3263bf3eadfa (diff) |
progress toward metadata support
-rw-r--r-- | index.js | 209 | ||||
-rw-r--r-- | package.json | 8 |
2 files changed, 155 insertions, 62 deletions
@@ -1,27 +1,38 @@ -var _log = console.log.bind(console) -window.console.log = window.log = function (data) { - var elem = document.getElementById('console') - elem.innerHTML += data + '<br>' - elem.scrollTop = elem.scrollHeight - _log(data) -} - -var _error = console.error.bind(console) -window.console.error = function (data) { - var elem = document.getElementById('console') - elem.innerHTML += '<span style="color: red;">' + data + '</span><br>' - elem.scrollTop = elem.scrollHeight - _error(data) -} +// var _log = console.log.bind(console) +// window.console.log = window.log = function () { +// var args = [].slice.apply(arguments) +// args = args.map(function (arg) { +// if (!Array.isArray(arg) && typeof arg === 'object') +// return JSON.stringify(arg) +// else +// return arg +// }) +// var elem = document.getElementById('console') +// elem.innerHTML += args.join(', ') + '<br>' +// elem.scrollTop = elem.scrollHeight +// _log.apply(null, args) +// } + +// var _error = console.error.bind(console) +// window.console.error = function () { +// var args = [].slice.apply(arguments) +// var elem = document.getElementById('console') +// elem.innerHTML += '<span style="color: red;">' + args.join(', ') + '</span><br>' +// elem.scrollTop = elem.scrollHeight +// _error.apply(null, args) +// } var $ = require('jquery') +var async = require('async') +var bncode = require('bncode') var DHT = require('bittorrent-dht') var hat = require('hat') var magnet = require('magnet-uri') +var portfinder = require('chrome-portfinder') var Swarm = require('bittorrent-swarm') -var MAX_PEERS = 60 -var TIMEOUT = 10000 +var MAX_PEERS = 200 +var WIRE_TIMEOUT = 10000 var METADATA_BLOCK_SIZE = 16 * 1024 var isChromeApp = !!(typeof window !== 'undefined' && window.chrome && @@ -54,47 +65,127 @@ var displayName = magnetToDisplayName(magnetUri) $('.infoHash span').text(infoHash) $('.displayName span').text(displayName) -var dht = new DHT(infoHash) - -dht.on('node', function (node, infoHash) { - var num = Number($('.dhtNodes span').text()) - $('.dhtNodes span').text(num + 1) +async.auto({ + dhtPort: function (cb) { + portfinder.getPort(cb) + }, + swarmPort: function (cb) { + portfinder.getPort(cb) + }, + dht: ['dhtPort', function (cb, r) { + var dht = new DHT(infoHash) + + dht.on('node', function (node, infoHash) { + var num = Number($('.dhtNodes span').text()) + $('.dhtNodes span').text(num + 1) + }) + + dht.on('peer', function (peer, infoHash) { + var num = Number($('.dhtPeers span').text()) + $('.dhtPeers span').text(num + 1) + // console.log('peer: ' + peer) + + swarm.add(peer) + }) + + dht.findPeers(MAX_PEERS) // TODO: should the DHT be concerned with max peers? + + // TODO: DHT should listen + // dht.listen(r.dhtPort) + }], + swarm: ['swarmPort', function (cb, r) { + var swarm = new Swarm(infoHash, peerId, { dht: true }) + + // TODO: add swarm listen and add ourselves to the DHT + + swarm.on('wire', function (wire) { + $('.connectedPeers span').text(swarm.wires.length) + + // Send KEEP-ALIVE (every 60s) so peers will not disconnect the wire + wire.setKeepAlive(true) + + // If peer supports DHT, send PORT message to report what port our DHT node + // is listening on + if (wire.peerExtensions.dht) { + // TODO: DHT doesn't support listening yet + // wire.port(dht.port) + } + + // When peer sends PORT, add them to the routing table + wire.on('port', function (port) { + console.log('PORT', port) + // TODO: DHT doesn't have a routing table + // dht.add(wire.remoteAddress, port) + }) + + // Time to wait before considering requests timed out + wire.setTimeout(WIRE_TIMEOUT) + + // Support extended messages: + // - ut_metadata (metadata fetching, trackerless torrents) + if (wire.peerExtensions) { + console.log('Wire ' + wire.remoteAddress + ' supports extended messages', wire.peerExtensions) + wire.extended(0, { + m: { + ut_metadata: 1 + } + // TODO - this should be set once we have metadata + // metadata_size: xx + }) + } + + wire.on('extended', function (ext, buf) { + console.log('Received extended message ' + ext + ' from ' + wire.remoteAddress) + + var dict + try { + console.log('decoding ' + buf.toString()) + dict = bncode.decode(buf.toString()) + } catch (e) { + console.error('Error decoding extended message: ' + e.message) + } + console.log(dict) + if (ext === 0) { // handshake + + if (dict.m.ut_metadata && dict.metadata_size) { + var metadataSize = dict.metadata_size + var numPieces = Math.ceil(metadataSize / METADATA_BLOCK_SIZE) + console.log('metadata size: ' + metadataSize) + console.log(numPieces + ' pieces') + + wire.metadata = new Buffer(metadataSize) + + // request all pieces + for (var piece = 0; piece < numPieces; piece++) { + wire.extended(dict.m.ut_metadata, { + msg_type: 0, + piece: piece + }) + } + } + + } else if (ext === 1) { // ut_metadata + console.log('got metadata data: ' + dict) + // {'msg_type': 1, 'piece': 0, 'total_size': 3425} + if (dict.msg_type === 1) { // data + var dataIndex = bncode.encode(dict).length + data.copy(wire.metadata, piece * METADATA_BLOCK_SIZE, dataIndex) + } + } + }) + + }) + + swarm.on('error', function (err) { + console.error(err.message) + }) + + // swarm.listen(r.dhtPort, function () { + // console.log('Swarm listening on port ' + r.dhtPort) + // }) + }] +}, function (err) { + if (err) console.error(err.message) + else console.log('Setup complete') }) -dht.on('peer', function (peer, infoHash) { - var num = Number($('.dhtPeers span').text()) - $('.dhtPeers span').text(num + 1) - console.log('peer: ' + peer) - - swarm.add(peer) -}) - -dht.findPeers(MAX_PEERS) // TODO: should the DHT be concerned with max peers? - -var swarm = new Swarm(infoHash, peerId) - -swarm.on('wire', function (wire) { - $('.connectedPeers span').text(swarm.wires.length) - - // Send KEEP-ALIVE (every 60s) so peers will not disconnect the wire - wire.setKeepAlive(true) - - // If peer supports DHT, send PORT message to report what port our DHT node - // is listening on - if (wire.peerExtensions.dht) { - // TODO: DHT doesn't support listening yet - // wire.port(dht.port) - } - - // When peer sends PORT, add them to the routing table - wire.on('port', function (port) { - console.log('PORT', port) - // TODO: DHT doesn't have a routing table - // dht.add(wire.remoteAddress, port) - }) - - // Time to wait before considering requests timed out - wire.setTimeout(TIMEOUT) - - -}) diff --git a/package.json b/package.json index 2d04656..c28ec4e 100644 --- a/package.json +++ b/package.json @@ -5,17 +5,19 @@ "homepage": "http://webtorrent.io", "main": "index.js", "dependencies": { - "async": "~0.2.9", + "async": "~0.2.10", "bittorrent-dht": "0.x", "bittorrent-protocol": "0.x", "bittorrent-swarm": "0.x", + "bncode": "~0.5.2", "browserify": "3.x", + "browserify-shim": "~3.2.2", "hat": "0.0.3", + "jquery": "~2.1.0", "magnet-uri": "0.x", "read-torrent": "~0.2.0", "speedometer": "~0.1.2", - "jquery": "~2.1.0", - "browserify-shim": "~3.2.2" + "portfinder": "~0.2.1" }, "devDependencies": { "nodemon": "1.x", |