Skip to content
This repository has been archived by the owner on Apr 24, 2023. It is now read-only.

A few BUGFIXES and new tests to cover those scenarios + multiple signalling servers! #89

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 25 additions & 14 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
'use strict'

const gulp = require('gulp')
const forEach = require('async/each')
const sigServer = require('./src/sig-server')

let sigS
let sigServers = []

gulp.task('test:node:before', boot)
gulp.task('test:node:after', stop)
gulp.task('test:browser:before', boot)
gulp.task('test:browser:after', stop)

function boot (done) {
const options = {
port: 15555,
host: '127.0.0.1'
}
const options = [
{
port: 15555,
host: '127.0.0.1'
},
{
port: 15556,
host: '127.0.0.1'
}]

sigServer.start(options, (err, server) => {
if (err) {
throw err
}
sigS = server
console.log('signalling on:', server.info.uri)
done()
})
forEach(options, (options, cb) => {
sigServer.start(options, (err, server) => {
if (err) {
throw err
}
sigServers.push(server)
console.log('signalling on:', server.info.uri)
cb()
})
}, done)
}

function stop (done) {
sigS.stop(done)
forEach(sigServers, (sigS, cb) => {
sigS.stop()
cb()
}, done)
}

require('aegir/gulp')(gulp)
46 changes: 23 additions & 23 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ function cleanUrlSIO (ma) {

class WebRTCStar {
constructor () {
this.maSelf = undefined

this.sioOptions = {
transports: ['websocket'],
'force new connection': true
Expand All @@ -60,7 +58,11 @@ class WebRTCStar {
callback = callback ? once(callback) : noop

const intentId = (~~(Math.random() * 1e9)).toString(36) + Date.now()
const sioClient = this.listenersRefs[Object.keys(this.listenersRefs)[0]].io
const keys = Object.keys(this.listenersRefs)
.filter((key) => cleanUrlSIO(ma) === cleanUrlSIO(multiaddr(key)))
const listener = this.listenersRefs[keys[0]]
if (!listener) return callback(new Error('signalling server not connected'))
const sioClient = listener.io

const spOptions = {
initiator: true,
Expand All @@ -73,11 +75,10 @@ class WebRTCStar {

const conn = new Connection(toPull.duplex(channel))
let connected = false

channel.on('signal', (signal) => {
sioClient.emit('ss-handshake', {
intentId: intentId,
srcMultiaddr: this.maSelf.toString(),
srcMultiaddr: listener.ma.toString(),
dstMultiaddr: ma.toString(),
signal: signal
})
Expand Down Expand Up @@ -130,13 +131,12 @@ class WebRTCStar {
listener.listen = (ma, callback) => {
callback = callback ? once(callback) : noop

this.maSelf = ma

const sioUrl = cleanUrlSIO(ma)

log('Dialing to Signalling Server on: ' + sioUrl)

listener.io = io.connect(sioUrl, sioOptions)
listener.ma = ma

listener.io.once('connect_error', callback)
listener.io.once('error', (err) => {
Expand All @@ -148,10 +148,26 @@ class WebRTCStar {
listener.io.emit('ss-join', ma.toString())
listener.io.on('ws-handshake', incommingDial)
listener.io.on('ws-peer', this._peerDiscovered)
this.listenersRefs[ma.toString()] = listener
listener.emit('listening')
callback()
})

listener.close = (callback) => {
callback = callback ? once(callback) : noop

listener.io.emit('ss-leave', ma.toString())
setImmediate(() => {
listener.io.disconnect()
listener.emit('close')
callback()
delete this.listenersRefs[ma.toString()]
})
}
listener.getAddrs = (callback) => {
setImmediate(() => callback(null, [ma]))
}

function incommingDial (offer) {
if (offer.answer || offer.err) {
return
Expand Down Expand Up @@ -188,22 +204,6 @@ class WebRTCStar {
}
}

listener.close = (callback) => {
callback = callback ? once(callback) : noop

listener.io.emit('ss-leave')

setImmediate(() => {
listener.emit('close')
callback()
})
}

listener.getAddrs = (callback) => {
setImmediate(() => callback(null, [this.maSelf]))
}

this.listenersRefs[multiaddr.toString()] = listener
return listener
}

Expand Down
108 changes: 107 additions & 1 deletion test/transport/dial.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ describe('dial', () => {
const maHSIP = '/ip4/188.166.203.82/tcp/20000'

const maLS = '/ip4/127.0.0.1/tcp/15555'
const maLS2 = '/ip4/127.0.0.1/tcp/15556'

// const maGen = (base, id) => multiaddr(`/libp2p-webrtc-star${base}/wss/ipfs/${id}`) // https
const maGen = (base, id) => multiaddr(`/libp2p-webrtc-star${base}/ws/ipfs/${id}`)

Expand Down Expand Up @@ -80,7 +82,7 @@ describe('dial', () => {
})

it('dial offline / non-existent node on IPv4, check callback', (done) => {
let maOffline = multiaddr('/libp2p-webrtc-star/ip4/127.0.0.1/tcp/15555/ws/ipfs/ABCD')
let maOffline = maGen(maLS, 'ABCD')
ws1.dial(maOffline, (err, conn) => {
expect(err).to.exist
done()
Expand All @@ -90,4 +92,108 @@ describe('dial', () => {
it.skip('dial on IPv6', (done) => {
// TODO IPv6 not supported yet
})
describe('complex dial scenarios', () => {
let ws1, ws2, ws3
const ma1a = maGen(maLS, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooA1')
const ma1b = maGen(maLS, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooA2')
const ma1c = maGen(maLS2, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooA3')
const ma2 = maGen(maLS, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooB1')
const ma3 = maGen(maLS2, 'QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooC1')
before((done) => {
series([
first,
second,
third,
fourth,
fifth
], done)

function first (next) {
ws1 = new WebRTCStar()

const listener = ws1.createListener((conn) => {
pull(conn, conn)
})

// close immediately
listener.listen(ma1a, () => {
listener.close(next)
})
}

function second (next) {
const listener = ws1.createListener((conn) => {
pull(conn, conn)
})

listener.listen(ma1b, next)
}
function third (next) {
const listener = ws1.createListener((conn) => {
pull(conn, conn)
})

listener.listen(ma1c, next)
}

function fourth (next) {
ws2 = new WebRTCStar()

const listener = ws2.createListener((conn) => {
pull(conn, conn)
})
listener.listen(ma2, next)
}
function fifth (next) {
ws3 = new WebRTCStar()

const listener = ws3.createListener((conn) => {
pull(conn, conn)
})
listener.listen(ma3, next)
}
})

it('dial closed listener should error', (done) => {
ws2.dial(ma1a, (err, conn) => {
expect(err).to.exist
done()
})
})

it('dial after first listener is closed and its signalling connection disconnected', (done) => {
ws1.dial(ma2, (err, conn) => {
expect(err).to.not.exist

const data = new Buffer('some data')

pull(
pull.values([data]),
conn,
pull.collect((err, values) => {
expect(err).to.not.exist
expect(values).to.be.eql([data])
done()
})
)
})
})
it('dial a second node on a different signaling server', (done) => {
ws1.dial(ma3, (err, conn) => {
expect(err).to.not.exist

const data = new Buffer('some data')

pull(
pull.values([data]),
conn,
pull.collect((err, values) => {
expect(err).to.not.exist
expect(values).to.be.eql([data])
done()
})
)
})
})
})
})
10 changes: 10 additions & 0 deletions test/transport/listen.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ describe('listen', () => {
})
})

it('listen on offline signalling server should error', (done) => {
let maOfflineSigServer = multiaddr('/libp2p-webrtc-star/ip4/127.0.0.0/tcp/15555/ws/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSooooA')
const listener = ws.createListener((conn) => {})
listener.listen(maOfflineSigServer, (err) => {
expect(err).to.exist
listener.once('close', done)
listener.close()
})
})

it.skip('close listener with connections, through timeout', (done) => {
// TODO ? Should this apply ?
})
Expand Down