2014-04-08 14:35:43 -07:00
|
|
|
|
|
|
|
var imports = require('soop').imports();
|
|
|
|
var EventEmitter= imports.EventEmitter || require('events').EventEmitter;
|
2014-04-23 09:44:20 -07:00
|
|
|
var bitcore = require('bitcore');
|
|
|
|
var util = bitcore.util;
|
2014-04-23 18:43:17 -07:00
|
|
|
var Key = bitcore.Key;
|
2014-04-08 22:20:28 -07:00
|
|
|
/*
|
|
|
|
* Emits
|
|
|
|
* 'networkChange'
|
|
|
|
* when network layout has change (new/lost peers, etc)
|
|
|
|
*
|
|
|
|
* 'data'
|
|
|
|
* when an unknown data type arrives
|
|
|
|
*
|
|
|
|
* Provides
|
2014-04-23 17:20:44 -07:00
|
|
|
* send(toPeerIds, {data}, cb?)
|
2014-04-08 22:20:28 -07:00
|
|
|
*
|
|
|
|
*/
|
2014-04-08 14:35:43 -07:00
|
|
|
|
2014-04-14 11:31:10 -07:00
|
|
|
function Network(opts) {
|
2014-04-17 12:58:07 -07:00
|
|
|
var self = this;
|
2014-04-23 17:20:44 -07:00
|
|
|
opts = opts || {};
|
|
|
|
this.peerId = opts.peerId;
|
|
|
|
this.apiKey = opts.apiKey || 'lwjd5qra8257b9';
|
|
|
|
this.debug = opts.debug || 3;
|
|
|
|
this.maxPeers = opts.maxPeers || 10;
|
|
|
|
this.opts = {
|
|
|
|
key: opts.key
|
|
|
|
};
|
2014-04-20 16:24:24 -07:00
|
|
|
this.connections = {};
|
2014-04-23 09:44:20 -07:00
|
|
|
this.copayerForPeer = {};
|
2014-04-17 12:27:15 -07:00
|
|
|
|
|
|
|
// For using your own peerJs server
|
2014-04-17 12:58:07 -07:00
|
|
|
['port', 'host', 'path', 'debug'].forEach(function(k) {
|
2014-04-23 17:20:44 -07:00
|
|
|
if (opts[k]) self.opts[k] = opts[k];
|
2014-04-17 12:58:07 -07:00
|
|
|
});
|
2014-04-08 14:35:43 -07:00
|
|
|
this.connectedPeers = [];
|
2014-04-18 10:40:16 -07:00
|
|
|
this.started = false;
|
2014-04-08 14:35:43 -07:00
|
|
|
}
|
|
|
|
|
2014-04-23 17:20:44 -07:00
|
|
|
Network.parent = EventEmitter;
|
2014-04-08 14:35:43 -07:00
|
|
|
|
|
|
|
// Array helpers
|
2014-04-14 11:31:10 -07:00
|
|
|
Network._arrayDiff = function(a, b) {
|
2014-04-08 14:35:43 -07:00
|
|
|
var seen = [];
|
|
|
|
var diff = [];
|
|
|
|
|
|
|
|
for (var i = 0; i < b.length; i++)
|
|
|
|
seen[b[i]] = true;
|
|
|
|
|
|
|
|
for (var j = 0; j < a.length; j++)
|
|
|
|
if (!seen[a[j]])
|
|
|
|
diff.push(a[j]);
|
|
|
|
|
|
|
|
return diff;
|
|
|
|
};
|
|
|
|
|
2014-04-14 11:31:10 -07:00
|
|
|
Network._inArray = function(el, array) {
|
2014-04-08 14:35:43 -07:00
|
|
|
return array.indexOf(el) > -1;
|
|
|
|
};
|
|
|
|
|
2014-04-14 11:31:10 -07:00
|
|
|
Network._arrayPushOnce = function(el, array) {
|
2014-04-08 14:35:43 -07:00
|
|
|
var ret = false;
|
2014-04-14 11:31:10 -07:00
|
|
|
if (!Network._inArray(el, array)) {
|
2014-04-08 14:35:43 -07:00
|
|
|
array.push(el);
|
|
|
|
ret = true;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
};
|
|
|
|
|
2014-04-14 11:31:10 -07:00
|
|
|
Network._arrayRemove = function(el, array) {
|
2014-04-08 14:35:43 -07:00
|
|
|
var pos = array.indexOf(el);
|
|
|
|
if (pos >= 0) array.splice(pos, 1);
|
|
|
|
return array;
|
|
|
|
};
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
Network.prototype.connectedCopayers = function() {
|
|
|
|
var ret =[];
|
|
|
|
for(var i in this.connectedPeers){
|
|
|
|
var copayerId =this.copayerForPeer[this.connectedPeers[i]];
|
|
|
|
if (copayerId) ret.push(copayerId);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
};
|
|
|
|
|
2014-04-14 11:31:10 -07:00
|
|
|
Network.prototype._onClose = function(peerId) {
|
2014-04-20 16:24:24 -07:00
|
|
|
delete this.connections[peerId];
|
2014-04-14 11:31:10 -07:00
|
|
|
this.connectedPeers = Network._arrayRemove(peerId, this.connectedPeers);
|
2014-04-17 07:46:49 -07:00
|
|
|
this._notifyNetworkChange();
|
2014-04-08 14:35:43 -07:00
|
|
|
};
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
Network.prototype._connectToCopayers = function(copayerIds) {
|
2014-04-08 14:35:43 -07:00
|
|
|
var self = this;
|
2014-04-23 12:02:23 -07:00
|
|
|
var arrayDiff= Network._arrayDiff(copayerIds, this.connectedCopayers());
|
|
|
|
arrayDiff.forEach(function(copayerId) {
|
|
|
|
console.log('### CONNECTING TO:', copayerId);
|
|
|
|
self.connectTo(copayerId);
|
2014-04-08 14:35:43 -07:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
Network.prototype._sendHello = function(copayerId) {
|
|
|
|
console.log('#### SENDING HELLO TO ', copayerId);
|
2014-04-23 09:44:20 -07:00
|
|
|
this.send(copayerId, {
|
2014-04-23 18:43:17 -07:00
|
|
|
type: 'hello',
|
2014-04-23 09:44:20 -07:00
|
|
|
copayerId: this.copayerId,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
Network.prototype._sendCopayers = function(copayerIds) {
|
|
|
|
console.log('#### SENDING PEER LIST: ', this.connectedPeers,this.connectedCopayers(), ' TO ', copayerIds?copayerIds: 'ALL');
|
|
|
|
this.send(copayerIds, {
|
|
|
|
type: 'copayers',
|
|
|
|
copayers: this.connectedCopayers(),
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
Network.prototype._addCopayer = function(copayerId, isInbound) {
|
2014-04-23 12:02:23 -07:00
|
|
|
var peerId = this.peerFromCopayer(copayerId);
|
|
|
|
this._addCopayerMap(peerId,copayerId);
|
|
|
|
var hasChanged = Network._arrayPushOnce(peerId, this.connectedPeers);
|
2014-04-23 09:44:20 -07:00
|
|
|
if (isInbound && hasChanged) {
|
|
|
|
this._sendCopayers(); //broadcast peer list
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (isInbound) {
|
|
|
|
this._sendCopayers(copayerId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Network.prototype._onData = function(data, isInbound, peerId) {
|
2014-04-23 18:43:17 -07:00
|
|
|
var sig, payload;
|
2014-04-09 07:05:25 -07:00
|
|
|
try {
|
2014-04-23 18:43:17 -07:00
|
|
|
var dataObj = JSON.parse(data);
|
|
|
|
sig = dataObj.sig;
|
|
|
|
payload= dataObj.payload;
|
|
|
|
|
2014-04-09 07:05:25 -07:00
|
|
|
} catch (e) {
|
2014-04-23 17:20:44 -07:00
|
|
|
console.log('### ERROR ON DATA: "%s" ', data, isInbound, e);
|
2014-04-09 07:05:25 -07:00
|
|
|
return;
|
|
|
|
};
|
2014-04-23 18:43:17 -07:00
|
|
|
|
|
|
|
console.log('### RECEIVED INBOUND?:%s TYPE: %s FROM %s: sig:%s',
|
|
|
|
isInbound, payload.type, peerId, sig, payload);
|
2014-04-23 09:44:20 -07:00
|
|
|
var self=this;
|
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
// TODO _func
|
|
|
|
if(payload.type === 'hello') {
|
|
|
|
var thisSig = this._sign(payload, this.copayerId);
|
|
|
|
if (thisSig !== sig) {
|
|
|
|
console.log('#### Peer sent WRONG hello. Closing connection.');
|
2014-04-23 09:44:20 -07:00
|
|
|
return;
|
2014-04-23 18:43:17 -07:00
|
|
|
}
|
|
|
|
console.log('#### Peer sent signed hello. Setting it up.'); //TODO
|
|
|
|
this._addCopayer(payload.copayerId, isInbound);
|
|
|
|
this._notifyNetworkChange( isInbound ? payload.copayerId : null);
|
|
|
|
this.emit('open');
|
|
|
|
return;
|
2014-04-23 09:44:20 -07:00
|
|
|
}
|
2014-04-08 14:35:43 -07:00
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
if (!this.copayerForPeer[peerId]) {
|
|
|
|
console.log('### Discarting message from unknow peer: ', peerId); //TODO
|
|
|
|
return;
|
|
|
|
}
|
2014-04-23 18:43:17 -07:00
|
|
|
|
|
|
|
// check sig
|
|
|
|
if (this.copayerForPeer[peerId]) {
|
|
|
|
var copayerIdBuf = new Buffer(this.copayerForPeer[peerId],'hex');
|
|
|
|
if (!bitcore.Message.verifyWithPubKey( copayerIdBuf, JSON.stringify(payload),
|
|
|
|
new Buffer(sig,'hex'))) {
|
|
|
|
|
|
|
|
console.log('[WebRTC.js.152] SIGNATURE VERIFICATION FAILED!!'); //TODO
|
|
|
|
// TODO close connection
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2014-04-23 09:44:20 -07:00
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
switch(payload.type) {
|
2014-04-23 09:44:20 -07:00
|
|
|
case 'copayers':
|
2014-04-23 12:02:23 -07:00
|
|
|
this._addCopayer(this.copayerForPeer[peerId], false);
|
2014-04-23 18:43:17 -07:00
|
|
|
this._connectToCopayers(payload.copayers);
|
2014-04-17 07:46:49 -07:00
|
|
|
this._notifyNetworkChange();
|
2014-04-08 14:35:43 -07:00
|
|
|
break;
|
|
|
|
case 'disconnect':
|
2014-04-23 18:43:17 -07:00
|
|
|
this._onClose(peerId);
|
2014-04-08 22:20:28 -07:00
|
|
|
break;
|
|
|
|
default:
|
2014-04-23 18:43:17 -07:00
|
|
|
this.emit('data', self.copayerForPeer[peerId], payload, isInbound);
|
2014-04-08 14:35:43 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-04-17 12:50:48 -07:00
|
|
|
Network.prototype._checkAnyPeer = function() {
|
|
|
|
if (!this.connectedPeers.length) {
|
|
|
|
console.log('EMIT openError: no more peers, not even you!');
|
2014-04-24 12:35:52 -07:00
|
|
|
this._cleanUp();
|
2014-04-17 12:50:48 -07:00
|
|
|
this.emit('openError');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-16 13:50:10 -07:00
|
|
|
Network.prototype._setupConnectionHandlers = function(dataConn, isInbound) {
|
2014-04-23 17:20:44 -07:00
|
|
|
var self = this;
|
2014-04-08 14:35:43 -07:00
|
|
|
|
|
|
|
dataConn.on('open', function() {
|
2014-04-23 12:02:23 -07:00
|
|
|
if (!Network._inArray(dataConn.peer, self.connectedPeers)
|
|
|
|
&& ! self.connections[dataConn.peer]) {
|
|
|
|
|
2014-04-20 16:24:24 -07:00
|
|
|
self.connections[dataConn.peer] = dataConn;
|
2014-04-08 14:35:43 -07:00
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
console.log('### DATA CONNECTION READY: %s (inbound: %s) AUTHENTICATING...',
|
2014-04-08 14:35:43 -07:00
|
|
|
dataConn.peer, isInbound);
|
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
// The connection peer send hello (with signature)
|
2014-04-23 09:44:20 -07:00
|
|
|
if(!isInbound)
|
2014-04-23 18:43:17 -07:00
|
|
|
self._sendHello(self.copayerForPeer[dataConn.peer]);
|
2014-04-08 14:35:43 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
dataConn.on('data', function(data) {
|
2014-04-23 09:44:20 -07:00
|
|
|
self._onData(data, isInbound, dataConn.peer);
|
2014-04-08 14:35:43 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
dataConn.on('error', function(e) {
|
2014-04-23 17:20:44 -07:00
|
|
|
console.log('### DATA ERROR', e); //TODO
|
2014-04-20 16:24:24 -07:00
|
|
|
self._onClose(dataConn.peer);
|
|
|
|
self._checkAnyPeer();
|
2014-04-17 12:50:48 -07:00
|
|
|
self.emit('dataError');
|
2014-04-08 14:35:43 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
dataConn.on('close', function() {
|
2014-04-12 09:37:41 -07:00
|
|
|
if (self.closing) return;
|
2014-04-20 16:24:24 -07:00
|
|
|
|
2014-04-23 17:20:44 -07:00
|
|
|
console.log('### CLOSE RECV FROM:', dataConn.peer);
|
2014-04-08 14:35:43 -07:00
|
|
|
self._onClose(dataConn.peer);
|
2014-04-17 12:50:48 -07:00
|
|
|
self._checkAnyPeer();
|
2014-04-08 14:35:43 -07:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
Network.prototype._notifyNetworkChange = function(newCopayerId) {
|
|
|
|
console.log('[WebRTC.js.164:_notifyNetworkChange:]', newCopayerId); //TODO
|
|
|
|
this.emit('networkChange', newCopayerId);
|
2014-04-08 14:35:43 -07:00
|
|
|
};
|
|
|
|
|
2014-04-14 11:31:10 -07:00
|
|
|
Network.prototype._setupPeerHandlers = function(openCallback) {
|
2014-04-23 17:20:44 -07:00
|
|
|
var self = this;
|
2014-04-08 14:35:43 -07:00
|
|
|
var p = this.peer;
|
|
|
|
|
2014-04-20 08:41:28 -07:00
|
|
|
p.on('open', function() {
|
|
|
|
self.connectedPeers = [self.peerId];
|
2014-04-23 12:02:23 -07:00
|
|
|
self.copayerForPeer[self.peerId]= self.copayerId;
|
|
|
|
|
2014-04-20 08:41:28 -07:00
|
|
|
return openCallback();
|
2014-04-08 14:35:43 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
p.on('error', function(err) {
|
2014-04-24 12:35:52 -07:00
|
|
|
if (!err.message.match(/Could\snot\sconnect\sto peer/)) {
|
|
|
|
console.log('### PEER ERROR:', err);
|
|
|
|
}
|
2014-04-17 12:50:48 -07:00
|
|
|
self._checkAnyPeer();
|
2014-04-08 14:35:43 -07:00
|
|
|
});
|
|
|
|
|
2014-04-09 07:05:25 -07:00
|
|
|
|
2014-04-24 13:54:43 -07:00
|
|
|
p.on('connection', function(dataConn) {
|
2014-04-09 07:05:25 -07:00
|
|
|
console.log('### NEW INBOUND CONNECTION %d/%d', self.connectedPeers.length, self.maxPeers);
|
|
|
|
if (self.connectedPeers.length >= self.maxPeers) {
|
|
|
|
console.log('### PEER REJECTED. PEER MAX LIMIT REACHED');
|
|
|
|
dataConn.on('open', function() {
|
|
|
|
console.log('### CLOSING CONN FROM:' + dataConn.peer);
|
|
|
|
dataConn.close();
|
|
|
|
});
|
2014-04-23 17:20:44 -07:00
|
|
|
} else {
|
2014-04-09 07:05:25 -07:00
|
|
|
self._setupConnectionHandlers(dataConn, true);
|
|
|
|
}
|
2014-04-08 14:35:43 -07:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-04-23 12:02:23 -07:00
|
|
|
|
|
|
|
Network.prototype._addCopayerMap = function(peerId, copayerId) {
|
|
|
|
if (!this.copayerForPeer[peerId]) {
|
|
|
|
console.log('ADDING COPAYER MAPPING: %s => %s', peerId, copayerId); //TODO
|
|
|
|
this.copayerForPeer[peerId]=copayerId;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
Network.prototype.setCopayerId = function(copayerId) {
|
2014-04-20 08:41:28 -07:00
|
|
|
if (this.started) {
|
2014-04-23 17:20:44 -07:00
|
|
|
throw new Error('network already started: can not change peerId')
|
2014-04-20 08:41:28 -07:00
|
|
|
}
|
2014-04-23 09:44:20 -07:00
|
|
|
this.copayerId = copayerId;
|
2014-04-23 18:43:17 -07:00
|
|
|
this.copayerIdBuf = new Buffer(copayerId,'hex');
|
2014-04-23 09:44:20 -07:00
|
|
|
this.peerId = this.peerFromCopayer(this.copayerId);
|
2014-04-23 12:02:23 -07:00
|
|
|
this._addCopayerMap(this.peerId,copayerId);
|
2014-04-20 08:41:28 -07:00
|
|
|
};
|
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
|
|
|
|
Network.prototype.setSigningKey = function(keyHex) {
|
|
|
|
if (this.started || this.signingKey) {
|
|
|
|
throw new Error ('network already started or key assigned: can not change key')
|
|
|
|
}
|
|
|
|
var k = new Key();
|
|
|
|
k.private = new Buffer(keyHex,'hex');
|
|
|
|
k.regenerateSync();
|
|
|
|
this.signingKey = k;
|
|
|
|
};
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
Network.prototype.peerFromCopayer = function(hex) {
|
|
|
|
return util.sha256(new Buffer(hex,'hex')).toString('hex');
|
|
|
|
};
|
2014-04-20 08:41:28 -07:00
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
Network.prototype.start = function(opts, openCallback) {
|
2014-04-18 14:25:51 -07:00
|
|
|
opts = opts || {};
|
|
|
|
var self = this;
|
2014-04-20 08:41:28 -07:00
|
|
|
if (this.started) return openCallback();
|
2014-04-18 14:25:51 -07:00
|
|
|
opts.connectedPeers = opts.connectedPeers || [];
|
2014-04-16 18:12:30 -07:00
|
|
|
|
2014-04-24 12:35:52 -07:00
|
|
|
if (!this.copayerId)
|
2014-04-23 18:43:17 -07:00
|
|
|
this.setCopayerId(opts.copayerId);
|
2014-04-24 12:35:52 -07:00
|
|
|
if (!this.signingKey)
|
2014-04-23 18:43:17 -07:00
|
|
|
this.setSigningKey(opts.signingKeyHex);
|
2014-04-23 09:44:20 -07:00
|
|
|
|
2014-04-24 12:35:52 -07:00
|
|
|
console.log('CREATING PEER INSTANCE:', this.peerId); //TODO
|
2014-04-17 12:58:07 -07:00
|
|
|
this.peer = new Peer(this.peerId, this.opts);
|
2014-04-08 14:35:43 -07:00
|
|
|
this._setupPeerHandlers(openCallback);
|
2014-04-23 17:20:44 -07:00
|
|
|
for (var i = 0; i < opts.connectedPeers.length; i++) {
|
2014-04-18 14:25:51 -07:00
|
|
|
var otherPeerId = opts.connectedPeers[i];
|
|
|
|
this.connectTo(otherPeerId);
|
|
|
|
}
|
2014-04-18 10:40:16 -07:00
|
|
|
this.started = true;
|
2014-04-08 14:35:43 -07:00
|
|
|
};
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
Network.prototype._sign = function(payload, copayerId) {
|
|
|
|
var ret='';
|
|
|
|
var str = JSON.stringify(payload);
|
|
|
|
if (payload.type ==='hello') {
|
2014-04-24 07:58:29 -07:00
|
|
|
ret = (
|
|
|
|
util.sha512hmac(
|
|
|
|
new Buffer(str),
|
|
|
|
new Buffer(copayerId,'hex')
|
|
|
|
)).toString('hex');
|
2014-04-23 18:43:17 -07:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!this.signingKey)
|
|
|
|
throw new Error ('no key to sign messages :(');
|
|
|
|
ret = bitcore.Message.sign(
|
|
|
|
str,
|
|
|
|
this.signingKey
|
|
|
|
).toString('hex');
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
};
|
|
|
|
|
|
|
|
Network.prototype._sendToOne = function(copayerId, payload, cb) {
|
2014-04-23 09:44:20 -07:00
|
|
|
var peerId = this.peerFromCopayer(copayerId);
|
2014-04-08 14:35:43 -07:00
|
|
|
if (peerId !== this.peerId) {
|
2014-04-20 16:24:24 -07:00
|
|
|
var dataConn = this.connections[peerId];
|
|
|
|
if (dataConn) {
|
2014-04-08 14:35:43 -07:00
|
|
|
var str = JSON.stringify({
|
2014-04-23 18:43:17 -07:00
|
|
|
sig: this._sign(payload, copayerId),
|
|
|
|
payload: payload
|
2014-04-08 14:35:43 -07:00
|
|
|
});
|
2014-04-20 16:24:24 -07:00
|
|
|
dataConn.send(str);
|
|
|
|
}
|
|
|
|
else {
|
2014-04-24 07:58:29 -07:00
|
|
|
console.log('[WebRTC.js.255] WARN: NO CONNECTION TO:', peerId); //TODO
|
2014-04-08 14:35:43 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (typeof cb === 'function') cb();
|
|
|
|
};
|
|
|
|
|
2014-04-23 18:43:17 -07:00
|
|
|
Network.prototype.send = function(copayerIds, payload, cb) {
|
2014-04-08 14:35:43 -07:00
|
|
|
var self=this;
|
2014-04-23 09:44:20 -07:00
|
|
|
if (!copayerIds) {
|
|
|
|
copayerIds = this.connectedCopayers();
|
2014-04-23 18:43:17 -07:00
|
|
|
payload.isBroadcast = 1;
|
2014-04-08 22:20:28 -07:00
|
|
|
}
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
if (Array.isArray(copayerIds)) {
|
|
|
|
var l = copayerIds.length;
|
2014-04-08 14:35:43 -07:00
|
|
|
var i = 0;
|
2014-04-23 09:44:20 -07:00
|
|
|
copayerIds.forEach(function(copayerId) {
|
2014-04-23 18:43:17 -07:00
|
|
|
self._sendToOne(copayerId, payload, function () {
|
2014-04-08 14:35:43 -07:00
|
|
|
if (++i === l && typeof cb === 'function') cb();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2014-04-23 09:44:20 -07:00
|
|
|
else if (typeof copayerIds === 'string')
|
2014-04-23 18:43:17 -07:00
|
|
|
self._sendToOne(copayerIds, payload, cb);
|
2014-04-08 14:35:43 -07:00
|
|
|
};
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
Network.prototype.connectTo = function(copayerId) {
|
2014-04-08 14:35:43 -07:00
|
|
|
var self = this;
|
2014-04-23 09:44:20 -07:00
|
|
|
var peerId = this.peerFromCopayer(copayerId);
|
2014-04-23 12:02:23 -07:00
|
|
|
this._addCopayerMap(peerId,copayerId);
|
|
|
|
|
2014-04-23 09:44:20 -07:00
|
|
|
console.log('### STARTING CONNECTION TO:', peerId, copayerId);
|
2014-04-08 14:35:43 -07:00
|
|
|
var dataConn = this.peer.connect(peerId, {
|
|
|
|
serialization: 'none',
|
|
|
|
reliable: true,
|
|
|
|
});
|
|
|
|
|
2014-04-16 13:50:10 -07:00
|
|
|
self._setupConnectionHandlers(dataConn, false);
|
2014-04-08 14:35:43 -07:00
|
|
|
};
|
|
|
|
|
2014-04-24 12:35:52 -07:00
|
|
|
Network.prototype._cleanUp = function() {
|
2014-04-24 13:54:43 -07:00
|
|
|
var self = this;
|
2014-04-24 12:35:52 -07:00
|
|
|
self.connectedPeers = [];
|
|
|
|
self.started = false;
|
|
|
|
self.peerId = null;
|
|
|
|
self.copayerId = null;
|
|
|
|
self.signingKey = null;
|
|
|
|
if (self.peer) {
|
|
|
|
console.log('## DESTROYING PEER INSTANCE'); //TODO
|
|
|
|
self.peer.disconnect();
|
|
|
|
self.peer.destroy();
|
|
|
|
self.peer = null;
|
|
|
|
}
|
|
|
|
self.closing = 0;
|
|
|
|
};
|
|
|
|
|
2014-04-15 08:17:28 -07:00
|
|
|
|
2014-04-18 14:25:51 -07:00
|
|
|
Network.prototype.disconnect = function(cb, forced) {
|
2014-04-08 14:35:43 -07:00
|
|
|
var self = this;
|
2014-04-12 09:37:41 -07:00
|
|
|
self.closing = 1;
|
2014-04-24 13:54:43 -07:00
|
|
|
self.send(null, { type: 'disconnect' }, function(){
|
|
|
|
self._cleanUp();
|
|
|
|
if (typeof cb === 'function') cb();
|
|
|
|
});
|
2014-04-08 14:35:43 -07:00
|
|
|
};
|
|
|
|
|
2014-04-14 11:31:10 -07:00
|
|
|
module.exports = require('soop')(Network);
|