94 lines
2.3 KiB
JavaScript
94 lines
2.3 KiB
JavaScript
'use strict'
|
|
|
|
const Emiter = require('events')
|
|
var util = require('util');
|
|
var net = require('net');
|
|
|
|
var PeerQueue = require('./peer-queue');
|
|
var Wire = require('./wire');
|
|
|
|
|
|
class Client extends Emiter
|
|
{
|
|
constructor(options) {
|
|
super();
|
|
this.timeout = 5000;
|
|
this.maxConnections = 200;
|
|
this.activeConnections = 0;
|
|
this.peers = new PeerQueue(this.maxConnections);
|
|
this.on('download', this._download);
|
|
|
|
// if (typeof options.ignore === 'function') {
|
|
// this.ignore = options.ignore;
|
|
//}
|
|
//else {
|
|
this.ignore = function (infohash, rinfo, ignore) {
|
|
ignore(false);
|
|
};
|
|
// }
|
|
}
|
|
|
|
_next(infohash, successful) {
|
|
var req = this.peers.shift(infohash, successful);
|
|
if (req) {
|
|
this.ignore(req.infohash.toString('hex'), req.rinfo, (drop) => {
|
|
if (!drop) {
|
|
this.emit('download', req.rinfo, req.infohash);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
_download(rinfo, infohash)
|
|
{
|
|
console.log('start download ' + infohash.toString('hex'));
|
|
this.activeConnections++;
|
|
|
|
var successful = false;
|
|
var socket = new net.Socket();
|
|
|
|
socket.setTimeout(this.timeout || 5000);
|
|
socket.connect(rinfo.port, rinfo.address, () => {
|
|
var wire = new Wire(infohash);
|
|
socket.pipe(wire).pipe(socket);
|
|
|
|
wire.on('metadata', (metadata, infoHash) => {
|
|
successful = true;
|
|
this.emit('complete', metadata, infoHash, rinfo);
|
|
socket.destroy();
|
|
});
|
|
|
|
wire.on('fail', () => {
|
|
socket.destroy();
|
|
});
|
|
|
|
wire.sendHandshake();
|
|
});
|
|
|
|
socket.on('error', (err) => {
|
|
socket.destroy();
|
|
});
|
|
|
|
socket.on('timeout', (err) => {
|
|
socket.destroy();
|
|
});
|
|
|
|
socket.once('close', () => {
|
|
this.activeConnections--;
|
|
this._next(infohash, successful);
|
|
});
|
|
}
|
|
|
|
add(rinfo, infohash) {
|
|
this.peers.push({infohash: infohash, rinfo: rinfo});
|
|
if (this.activeConnections < this.maxConnections && this.peers.length() > 0) {
|
|
this._next();
|
|
}
|
|
}
|
|
|
|
isIdle() {
|
|
return this.peers.length() === 0;
|
|
}
|
|
}
|
|
|
|
module.exports = Client; |