diff --git a/.travis.yml b/.travis.yml index 794a9294..df5c401c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,3 +4,5 @@ node_js: - "node" - "4" - "0.12" +before_script: + - export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start diff --git a/lib/client/websocket-tracker.js b/lib/client/websocket-tracker.js index ddb5e29d..d3a0e21f 100644 --- a/lib/client/websocket-tracker.js +++ b/lib/client/websocket-tracker.js @@ -87,8 +87,18 @@ WebSocketTracker.prototype.destroy = function (cb) { if (self.destroyed) return cb(null) self.destroyed = true clearInterval(self.interval) + clearTimeout(self.reconnectTimer) - delete socketPool[self.announceUrl] + // Destroy peers + for (var peerId in self.peers) { + var peer = self.peers[peerId] + clearTimeout(peer.trackerTimeout) + peer.destroy() + } + delete self.peers + + // Close socked + if (socketPool[self.announceUrl]) socketPool[self.announceUrl].consumers-- self.socket.removeListener('connect', self._onSocketConnectBound) self.socket.removeListener('data', self._onSocketDataBound) @@ -100,11 +110,16 @@ WebSocketTracker.prototype.destroy = function (cb) { self._onSocketDataBound = null self._onSocketCloseBound = null - self.socket.on('error', noop) // ignore all future errors - try { - self.socket.destroy(cb) - } catch (err) { - cb(null) + if (socketPool[self.announceUrl].consumers === 0) { + delete socketPool[self.announceUrl] + + self.socket.on('error', noop) // ignore all future errors + + try { + self.socket.destroy(cb) + } catch (err) { + if (cb) cb() + } } self.socket = null @@ -122,7 +137,10 @@ WebSocketTracker.prototype._openSocket = function () { self.socket = socketPool[self.announceUrl] if (!self.socket) { self.socket = socketPool[self.announceUrl] = new Socket(self.announceUrl) + self.socket.consumers = 1 self.socket.on('connect', self._onSocketConnectBound) + } else { + socketPool[self.announceUrl].consumers++ } self.socket.on('data', self._onSocketDataBound) @@ -291,11 +309,11 @@ WebSocketTracker.prototype._startReconnectTimer = function () { var ms = Math.floor(Math.random() * RECONNECT_VARIANCE) + Math.min(Math.pow(2, self.retries) * RECONNECT_MINIMUM, RECONNECT_MAXIMUM) self.reconnecting = true - var reconnectTimer = setTimeout(function () { + self.reconnectTimer = setTimeout(function () { self.retries++ self._openSocket() }, ms) - if (reconnectTimer.unref) reconnectTimer.unref() + if (self.reconnectTimer.unref) self.reconnectTimer.unref() debug('reconnecting socket in %s ms', ms) } diff --git a/package.json b/package.json index c4bb5764..87e9a040 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "xtend": "^4.0.0" }, "devDependencies": { + "electron-webrtc": "^0.1.0", "magnet-uri": "^5.0.0", "parse-torrent": "^5.0.0", "standard": "^6.0.4", diff --git a/server.js b/server.js index c4791ec0..ab8aa951 100644 --- a/server.js +++ b/server.js @@ -599,6 +599,7 @@ Server.prototype._onWebSocketClose = function (socket) { var swarm = self.torrents[infoHash] if (swarm) { swarm.announce({ + type: 'ws', event: 'stopped', numwant: 0, peer_id: socket.peerId diff --git a/test/server.js b/test/server.js index 1934f756..30b38de1 100644 --- a/test/server.js +++ b/test/server.js @@ -1,6 +1,7 @@ var Client = require('../') var common = require('./common') var test = require('tape') +var wrtc var infoHash = '4cb67059ed6bd08362da625b3ae77f6f4a075705' var peerId = new Buffer('01234567890123456789') @@ -25,7 +26,7 @@ function serverTest (t, serverType, serverFamily) { infoHash: infoHash, length: torrentLength, announce: [ announceUrl ] - }) + }, { wrtc: wrtc }) client1.start() @@ -45,14 +46,19 @@ function serverTest (t, serverType, serverFamily) { t.equal(swarm.complete, 0) t.equal(swarm.incomplete, 1) t.equal(Object.keys(swarm.peers).length, 1) - t.deepEqual(swarm.peers[hostname + ':6881'], { - type: serverType, - ip: clientIp, - port: 6881, - peerId: peerId.toString('hex'), - complete: false, - socket: undefined - }) + + if (serverType !== 'ws') { + t.deepEqual(swarm.peers[hostname + ':6881'], { + type: serverType, + ip: clientIp, + port: 6881, + peerId: peerId.toString('hex'), + complete: false, + socket: undefined + }) + } else { + t.equal(swarm.peers[peerId.toString('hex')].complete, false) + } client1.complete() @@ -73,7 +79,7 @@ function serverTest (t, serverType, serverFamily) { infoHash: infoHash, length: torrentLength, announce: [ announceUrl ] - }) + }, { wrtc: wrtc }) client2.start() @@ -82,7 +88,7 @@ function serverTest (t, serverType, serverFamily) { }) client2.once('peer', function (addr) { - t.ok(addr === hostname + ':6881' || addr === hostname + ':6882') + t.ok(addr === hostname + ':6881' || addr === hostname + ':6882' || addr.id === peerId.toString('hex')) client2.stop() client2.once('update', function (data) { @@ -109,6 +115,21 @@ function serverTest (t, serverType, serverFamily) { }) } +test('create daemon', function (t) { + wrtc = require('electron-webrtc')() + wrtc.electronDaemon.once('ready', t.end) +}) + +test('websocket server', function (t) { + serverTest(t, 'ws', 'inet') +}) + +// cleanup +test('cleanup electron-eval daemon', function (t) { + wrtc.close() + t.end() +}) + test('http ipv4 server', function (t) { serverTest(t, 'http', 'inet') })