internet
Version:
Framework for creating peer-to-peer browser networks
153 lines (110 loc) • 3.73 kB
JavaScript
var JSONProtocol = require('./JSONProtocol.js'),
its = require('its'),
Emitter = require('events').EventEmitter;
function notImplemented(){
throw new Error('This method is not implemented');
}
function Connection(address, peers, options){
its.string(address);
its.defined(peers);
this.address = address;
this.peers = peers;
if(options){
if(options.emitter) this.emitter = options.emitter;
if(options.firewall) this.acceptRTCConnection = options.firewall;
}
if(!this.emitter) this.emitter = new Connection.Emitter();
}
// Circular dependency solved in WebRTCConnection.js
Connection.createWebRTCConnection = null;
Connection.Emitter = Emitter;
Connection.prototype = Object.create(JSONProtocol.prototype);
Connection.prototype.on = function(){
this.emitter.on.apply(this.emitter, arguments);
return this;
};
Connection.prototype.removeListener = function(){
this.emitter.removeListener.apply(this.emitter, arguments);
return this;
};
Connection.prototype.send = JSONProtocol.prototype.writeMessage;
Connection.prototype.getPeer = function(address){
return this.peers.get(address);
};
Connection.prototype.addPeer = function(peer){
return this.peers.add(peer);
};
Connection.prototype.getPeers = function() {
return this.peers.get();
};
function isString(candidate){
return Object.prototype.toString.call(candidate) === '[object String]';
}
Connection.prototype.connect = function(config){
if(isString(config)){
config = {address: config};
}
var self = this,
firewall = config.firewall || this.firewall,
peer = Connection.createWebRTCConnection(config, this.peers, this, {firewall: firewall});
peer.writeOffer(config);
this.peers.add(peer);
peer.on('close', function(){
self.peers.remove(peer);
self.emitter.emit('disconnection', peer);
});
this.emitter.emit('connection', peer);
return peer;
};
Connection.prototype.readMessage = function(message){
this.emitter.emit('message', message);
};
Connection.prototype.readArrayBuffer = function(message){
this.emitter.emit('arraybuffer', message);
};
Connection.prototype.acceptRTCConnection = function(description, data){
return true;
};
Connection.prototype.readRelay = function(peerAddress, message){
var peer = this.getPeer(peerAddress);
if(!peer){
this.emitter.emit('error', new Error("Unknown peer at address: " + peerAddress));
return;
}
peer.writeRelayedMessage(this.address, message);
};
Connection.prototype.readRelayedIceCandidate = function(peerAddress, candidate){
var peer = this.getPeer(peerAddress);
if(!peer){
this.emitter.emit('error', new Error("Unknown peer at address: " + peerAddress));
return;
}
peer.readIceCandidate(candidate);
};
Connection.prototype.readRelayedOffer = function(peerAddress, description, data){
if(!this.acceptRTCConnection(description, data)) return false;
var self = this,
peer = Connection.createWebRTCConnection({address:peerAddress}, this.peers, this, {firewall: this.firewall});
this.addPeer(peer);
peer.on('close', function(){
self.peers.remove(peer);
self.emitter.emit('disconnection', peer);
});
peer.readOffer(description);
peer.writeAnswer();
this.emitter.emit('connection', peer);
};
Connection.prototype.readRelayedAnswer = function(peerAddress, description){
var peer = this.getPeer(peerAddress);
if(!peer){
this.emitter.emit('error', new Error("Unknown peer at address: " + peerAddress));
return;
}
peer.readAnswer(description);
};
Connection.prototype.close = notImplemented; // implemented higher up
Connection.prototype.getReadyState = notImplemented; // implemented higher up
Connection.prototype.isOpen = function(){
return this.getReadyState() === 'open';
};
module.exports = Connection;