rats-search/lib/client.js
2016-12-31 06:32:56 +03:00

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;