Finished support for new connector type

This commit is contained in:
DadaMonad
2014-11-25 15:51:30 +00:00
parent 03925ab32f
commit e1900e8561
170 changed files with 73970 additions and 8705 deletions

View File

@@ -0,0 +1,41 @@
{
"name": "peerjs-connector",
"version": "0.0.0",
"authors": [
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
],
"description": "Connect to other users via PeerJS. The interface is standardized, so you can use other connectors without changing your code.",
"main": [
"peerjs-connector.js",
"peerjs-connector.html"
],
"moduleType": [
"globals",
"node"
],
"keywords": [
"peerjs"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"polymer": "Polymer/polymer#~0.5.1"
},
"homepage": "https://github.com/DadaMonad/peerjs-connector",
"_release": "0.0.0",
"_resolution": {
"type": "version",
"tag": "v0.0.0",
"commit": "3bfeb2831ff0a494531a4ed438e149a256c6fb71"
},
"_source": "git://github.com/DadaMonad/peerjs-connector.git",
"_target": "~0.0.0",
"_originalSource": "peerjs-connector",
"_direct": true
}

View File

@@ -0,0 +1,180 @@
```js
(function() {
var PeerJsConnector,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
window.PeerJsConnector = PeerJsConnector = (function() {
function PeerJsConnector(id, options) {
var exchangeConnections, joinConnections, that;
this.id = id;
this._addConnection = __bind(this._addConnection, this);
that = this;
this.isConnected = false;
this.computeWhenConnected = [];
this.connections = {};
this.unsynced_connections = {};
this.receive_handlers = [];
this.conn = new Peer(arguments[0], arguments[1]);
this.conn.on('error', function(err) {
throw new Error("Peerjs connector: " + err);
});
this.conn.on('disconnected', function() {
throw new Error("Peerjs connector disconnected from signalling server. Cannot accept new connections. Not fatal, but not so good either..");
});
this.conn.on('disconnect', function() {
return that.conn.reconnect();
});
this.conn.on('connection', this._addConnection);
exchangeConnections = function() {
var conns, peer, peerid;
conns = (function() {
var _ref, _results;
_ref = that.connections;
_results = [];
for (peerid in _ref) {
peer = _ref[peerid];
_results.push(peerid);
}
return _results;
})();
return conns;
};
joinConnections = function(peers) {
var peer, _i, _len;
for (_i = 0, _len = peers.length; _i < _len; _i++) {
peer = peers[_i];
if (this.unsynced_connections[peer.peer] == null) {
this.unsynced_connections[peer.peer] = peer;
that.join(peer);
}
}
return true;
};
this.syncProcessOrder = [exchangeConnections, joinConnections];
}
PeerJsConnector.prototype.whenConnected = function(f) {
if (this.isConnected) {
return f.call(this);
} else {
return this.computeWhenConnected.push(f);
}
};
PeerJsConnector.prototype.whenReceiving = function(f) {
return this.receive_handlers.push(f);
};
PeerJsConnector.prototype.send = function(peers, message) {
return this.whenConnected((function(_this) {
return function() {
var peer, _i, _len, _results;
_results = [];
for (_i = 0, _len = peers.length; _i < _len; _i++) {
peer = peers[_i];
_results.push(_this.connections[peer].send(message));
}
return _results;
};
})(this));
};
PeerJsConnector.prototype.broadcast = function(message) {
return this.whenConnected((function(_this) {
return function() {
var peer, peerid, _ref, _results;
_ref = _this.connections;
_results = [];
for (peerid in _ref) {
peer = _ref[peerid];
_results.push(peer.send(message));
}
return _results;
};
})(this));
};
PeerJsConnector.prototype.whenSyncing = function() {
var f, _i, _len, _results;
_results = [];
for (_i = 0, _len = arguments.length; _i < _len; _i++) {
f = arguments[_i];
_results.push(this.syncProcessOrder.push(f));
}
return _results;
};
PeerJsConnector.prototype.join = function(peerid) {
var peer;
if ((this.connections[peerid] == null) && peerid !== this.id) {
peer = this.conn.connect(peerid, {
reliable: true
});
this._addConnection(peer);
return true;
} else {
return false;
}
};
PeerJsConnector.prototype._addConnection = function(peer) {
return peer.on('open', (function(_this) {
return function() {
var current_sync_function, current_sync_i, that;
_this.currentlyadding = peer;
that = _this;
peer.send(that.syncProcessOrder[0]());
current_sync_function = that.syncProcessOrder[1];
current_sync_i = 0;
return peer.on('data', function(data) {
var f, isEmpty, _i, _j, _len, _len1, _ref, _ref1, _results;
console.log("receive data: " + (JSON.stringify(data)));
current_sync_i++;
if (current_sync_i < that.syncProcessOrder.length) {
peer.send(current_sync_function.call(that, data));
return current_sync_function = that.syncProcessOrder[current_sync_i];
} else if (current_sync_i === that.syncProcessOrder.length) {
that.connections[peer.peer] = peer;
peer.on('close', function() {
return delete that.connections[peer.peer];
});
delete that.unsynced_connections[peer.peer];
isEmpty = function(os) {
var o;
for (o in os) {
return false;
}
return true;
};
if (isEmpty(that.unsynced_connections)) {
that.isConnected = true;
_ref = that.computeWhenConnected;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
f = _ref[_i];
f.call(that);
}
return that.computeWhenConnected = [];
}
} else {
_ref1 = that.receive_handlers;
_results = [];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
f = _ref1[_j];
_results.push(f(peer.peer, data));
}
return _results;
}
});
};
})(this));
};
return PeerJsConnector;
})();
}).call(this);
//# sourceMappingURL=sourcemaps/peerjs-connector.js.map
```

View File

@@ -0,0 +1,30 @@
{
"name": "peerjs-connector",
"version": "0.0.0",
"authors": [
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"
],
"description": "Connect to other users via PeerJS. The interface is standardized, so you can use other connectors without changing your code.",
"main": [
"peerjs-connector.js",
"peerjs-connector.html"
],
"moduleType": [
"globals",
"node"
],
"keywords": [
"peerjs"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"polymer": "Polymer/polymer#~0.5.1"
}
}

View File

@@ -0,0 +1,35 @@
gulp = require 'gulp'
coffee = require 'gulp-coffee'
concat = require 'gulp-concat'
uglify = require 'gulp-uglify'
sourcemaps = require 'gulp-sourcemaps'
plumber = require 'gulp-plumber'
paths =
scripts: ['./lib/**/*.coffee']
gulp.task 'scripts', [], ()->
return gulp.src(paths.scripts)
.pipe(plumber())
.pipe(sourcemaps.init())
.pipe(coffee())
#.pipe(uglify())
.pipe(sourcemaps.write('./sourcemaps/'))
.pipe(gulp.dest('./'))
# Rerun the task when a file changes
gulp.task 'watch', ()->
gulp.watch(paths.scripts, ['scripts'])
gulp.task('default', ['watch', 'scripts'])

View File

@@ -0,0 +1,29 @@
new Polymer 'peerjs-connector',
join: (id)->
idChanged: (old_val,new_val)->
if this.is_initialized
throw new Error "You must not set the user_id twice!"
else
this.initializeConnection()
initializeConnection: ()->
if this.conn_id?
console.log("now initializing")
options = {}
writeIfAvailable = (name, value)->
if value?
options[name] = value
writeIfAvailable 'key', this.key
writeIfAvailable 'host', this.host
writeIfAvailable 'port', this.port
writeIfAvailable 'path', this.path
writeIfAvailable 'secure', this.secure
writeIfAvailable 'debug', this.debug
this.is_initialized = true;
this.connector = new PeerJsConnector this.conn_id, options
ready: ()->
if this.conn_id != null
this.initializeConnection()

View File

@@ -0,0 +1,138 @@
window.PeerJsConnector = class PeerJsConnector
constructor: (@id, options)->
that = this
@isConnected = false
@computeWhenConnected = []
@connections = {}
@unsynced_connections = {}
@receive_handlers = []
@conn = new Peer arguments[0], arguments[1]
@conn.on 'error', (err)->
throw new Error "Peerjs connector: #{err}"
@conn.on 'disconnected', ()->
throw new Error "Peerjs connector disconnected from signalling server. Cannot accept new connections. Not fatal, but not so good either.."
@conn.on 'disconnect', ()->
that.conn.reconnect()
@conn.on 'connection', @_addConnection
# send all connection ids
exchangeConnections = ()->
conns = for peerid,peer of that.connections
peerid
conns
joinConnections = (peers)->
for peer in peers
if not @unsynced_connections[peer.peer]?
@unsynced_connections[peer.peer] = peer
that.join peer
true
@syncProcessOrder = [exchangeConnections, joinConnections]
#
# Execute an function _when_ we are connected. If not connected, wait until connected.
# @param f {Function} Will be executed on the PeerJs-Connector context. No parameters.
#
whenConnected: (f)->
if @isConnected
f.call this
else
@computeWhenConnected.push f
#
# Execute an function _when_ a message is received.
# @param f {Function} Will be executed on the PeerJs-Connector context. f will be called with (sender_id, broadcast {true|false}, message).
#
whenReceiving: (f)->
@receive_handlers.push f
#
# Send a message to a (sub)-set of peers.
# @param peers {Array<connection_ids>} A set of ids.
# @param message {Object} The message to send.
#
send: (peers, message)->
@whenConnected ()=>
for peer in peers
@connections[peer].send message
#
# Broadcast a message to all connected peers.
# @param message {Object} The message to broadcast.
#
broadcast: (message)->
@whenConnected ()=>
for peerid,peer of @connections
peer.send message
#
# Define how you want to handle the sync process of two users.
# This is a synchronous handshake. Every user will perform exactly the same actions at the same time. E.g.
# @example
# whenSyncing(function(){ // first call must not have parameters!
# return this.id; // Send the id of this connector.
# },function(peerid){ // you receive the peerid of the other connections.
# // you can do something with the peerid
# // return "you are my friend"; // you could send another massage.
# }); // this is the end of the sync process.
#
whenSyncing: ()->
for f in arguments
@syncProcessOrder.push f
#
# Join a communication room. In case of peerjs, you just have to join to one other client. This connector will join to the other peers automatically.
# @param id {String} The connection id of another client.
#
join: (peerid)->
if not @connections[peerid]? and peerid isnt @id
peer = @conn.connect peerid, {reliable: true}
@_addConnection peer
true
else
false
_addConnection: (peer)=>
peer.on 'open', ()=>
@currentlyadding = peer
that = @
peer.send that.syncProcessOrder[0]()
current_sync_function = that.syncProcessOrder[1];
current_sync_i = 0
peer.on 'data', (data)->
console.log("receive data: #{JSON.stringify data}")
current_sync_i++
if current_sync_i < that.syncProcessOrder.length
peer.send current_sync_function.call that, data
current_sync_function = that.syncProcessOrder[current_sync_i]
else if current_sync_i is that.syncProcessOrder.length
that.connections[peer.peer] = peer
peer.on 'close', ()->
delete that.connections[peer.peer]
delete that.unsynced_connections[peer.peer]
isEmpty = (os)->
for o of os
return false
return true
if isEmpty(that.unsynced_connections)
that.isConnected = true
for f in that.computeWhenConnected
f.call(that)
that.computeWhenConnected = []
else
for f in that.receive_handlers
f peer.peer, data

View File

@@ -0,0 +1,25 @@
{
"name": "peerjs-connector",
"version": "0.0.0",
"description": "Connect to other users via PeerJS. The interface is standardized, so you can use other connectors without changing your code. ",
"main": "peerjs-connector.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"peerjs"
],
"author": "Kevin Jahns <kevin.jahns@rwth-aachen.de>",
"license": "MIT",
"dependencies": {
"peerjs": "~0.3.14"
},
"devDependencies": {
"gulp-sourcemaps": "~1.2.8",
"gulp-concat": "~2.4.1",
"gulp-coffee": "~2.2.0",
"gulp-uglify": "~1.0.1",
"gulp": "~3.8.10",
"coffee-script": "~1.8.0"
}
}

View File

@@ -0,0 +1,40 @@
(function() {
new Polymer('peerjs-connector', {
join: function(id) {},
idChanged: function(old_val, new_val) {
if (this.is_initialized) {
throw new Error("You must not set the user_id twice!");
} else {
return this.initializeConnection();
}
},
initializeConnection: function() {
var options, writeIfAvailable;
if (this.conn_id != null) {
console.log("now initializing");
options = {};
writeIfAvailable = function(name, value) {
if (value != null) {
return options[name] = value;
}
};
writeIfAvailable('key', this.key);
writeIfAvailable('host', this.host);
writeIfAvailable('port', this.port);
writeIfAvailable('path', this.path);
writeIfAvailable('secure', this.secure);
writeIfAvailable('debug', this.debug);
this.is_initialized = true;
return this.connector = new PeerJsConnector(this.conn_id, options);
}
},
ready: function() {
if (this.conn_id !== null) {
return this.initializeConnection();
}
}
});
}).call(this);
//# sourceMappingURL=sourcemaps/peerjs-connector-polymer.js.map

View File

@@ -0,0 +1,10 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="peerjs-connector" hidden attributes="conn_id connector key host port path secure debug">
<script src="../bower_components/peerjs/peer.min.js"></script>
<script src="./peerjs-connector.js"></script>
<template>
</template>
<script src="./peerjs-connector-polymer.js"></script>
</polymer-element>

View File

@@ -0,0 +1,177 @@
(function() {
var PeerJsConnector,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
window.PeerJsConnector = PeerJsConnector = (function() {
function PeerJsConnector(id, options) {
var exchangeConnections, joinConnections, that;
this.id = id;
this._addConnection = __bind(this._addConnection, this);
that = this;
this.isConnected = false;
this.computeWhenConnected = [];
this.connections = {};
this.unsynced_connections = {};
this.receive_handlers = [];
this.conn = new Peer(arguments[0], arguments[1]);
this.conn.on('error', function(err) {
throw new Error("Peerjs connector: " + err);
});
this.conn.on('disconnected', function() {
throw new Error("Peerjs connector disconnected from signalling server. Cannot accept new connections. Not fatal, but not so good either..");
});
this.conn.on('disconnect', function() {
return that.conn.reconnect();
});
this.conn.on('connection', this._addConnection);
exchangeConnections = function() {
var conns, peer, peerid;
conns = (function() {
var _ref, _results;
_ref = that.connections;
_results = [];
for (peerid in _ref) {
peer = _ref[peerid];
_results.push(peerid);
}
return _results;
})();
return conns;
};
joinConnections = function(peers) {
var peer, _i, _len;
for (_i = 0, _len = peers.length; _i < _len; _i++) {
peer = peers[_i];
if (this.unsynced_connections[peer.peer] == null) {
this.unsynced_connections[peer.peer] = peer;
that.join(peer);
}
}
return true;
};
this.syncProcessOrder = [exchangeConnections, joinConnections];
}
PeerJsConnector.prototype.whenConnected = function(f) {
if (this.isConnected) {
return f.call(this);
} else {
return this.computeWhenConnected.push(f);
}
};
PeerJsConnector.prototype.whenReceiving = function(f) {
return this.receive_handlers.push(f);
};
PeerJsConnector.prototype.send = function(peers, message) {
return this.whenConnected((function(_this) {
return function() {
var peer, _i, _len, _results;
_results = [];
for (_i = 0, _len = peers.length; _i < _len; _i++) {
peer = peers[_i];
_results.push(_this.connections[peer].send(message));
}
return _results;
};
})(this));
};
PeerJsConnector.prototype.broadcast = function(message) {
return this.whenConnected((function(_this) {
return function() {
var peer, peerid, _ref, _results;
_ref = _this.connections;
_results = [];
for (peerid in _ref) {
peer = _ref[peerid];
_results.push(peer.send(message));
}
return _results;
};
})(this));
};
PeerJsConnector.prototype.whenSyncing = function() {
var f, _i, _len, _results;
_results = [];
for (_i = 0, _len = arguments.length; _i < _len; _i++) {
f = arguments[_i];
_results.push(this.syncProcessOrder.push(f));
}
return _results;
};
PeerJsConnector.prototype.join = function(peerid) {
var peer;
if ((this.connections[peerid] == null) && peerid !== this.id) {
peer = this.conn.connect(peerid, {
reliable: true
});
this._addConnection(peer);
return true;
} else {
return false;
}
};
PeerJsConnector.prototype._addConnection = function(peer) {
return peer.on('open', (function(_this) {
return function() {
var current_sync_function, current_sync_i, that;
_this.currentlyadding = peer;
that = _this;
peer.send(that.syncProcessOrder[0]());
current_sync_function = that.syncProcessOrder[1];
current_sync_i = 0;
return peer.on('data', function(data) {
var f, isEmpty, _i, _j, _len, _len1, _ref, _ref1, _results;
console.log("receive data: " + (JSON.stringify(data)));
current_sync_i++;
if (current_sync_i < that.syncProcessOrder.length) {
peer.send(current_sync_function.call(that, data));
return current_sync_function = that.syncProcessOrder[current_sync_i];
} else if (current_sync_i === that.syncProcessOrder.length) {
that.connections[peer.peer] = peer;
peer.on('close', function() {
return delete that.connections[peer.peer];
});
delete that.unsynced_connections[peer.peer];
isEmpty = function(os) {
var o;
for (o in os) {
return false;
}
return true;
};
if (isEmpty(that.unsynced_connections)) {
that.isConnected = true;
_ref = that.computeWhenConnected;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
f = _ref[_i];
f.call(that);
}
return that.computeWhenConnected = [];
}
} else {
_ref1 = that.receive_handlers;
_results = [];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
f = _ref1[_j];
_results.push(f(peer.peer, data));
}
return _results;
}
});
};
})(this));
};
return PeerJsConnector;
})();
}).call(this);
//# sourceMappingURL=sourcemaps/peerjs-connector.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["peerjs-connector-polymer.coffee"],"names":[],"mappings":"AACA;AAAA,EAAI,IAAA,OAAA,CAAQ,kBAAR,EACF;AAAA,IAAA,IAAA,EAAM,SAAC,EAAD,GAAA,CAAN;AAAA,IACA,SAAA,EAAW,SAAC,OAAD,EAAS,OAAT,GAAA;AACT,MAAA,IAAG,IAAI,CAAC,cAAR;AACE,cAAU,IAAA,KAAA,CAAM,qCAAN,CAAV,CADF;OAAA,MAAA;eAGE,IAAI,CAAC,oBAAL,CAAA,EAHF;OADS;IAAA,CADX;AAAA,IAOA,oBAAA,EAAsB,SAAA,GAAA;AACpB,UAAA,yBAAA;AAAA,MAAA,IAAG,oBAAH;AACE,QAAA,OAAO,CAAC,GAAR,CAAY,kBAAZ,CAAA,CAAA;AAAA,QACA,OAAA,GAAU,EADV,CAAA;AAAA,QAEA,gBAAA,GAAmB,SAAC,IAAD,EAAO,KAAP,GAAA;AACjB,UAAA,IAAG,aAAH;mBACE,OAAQ,CAAA,IAAA,CAAR,GAAgB,MADlB;WADiB;QAAA,CAFnB,CAAA;AAAA,QAKA,gBAAA,CAAiB,KAAjB,EAAwB,IAAI,CAAC,GAA7B,CALA,CAAA;AAAA,QAMA,gBAAA,CAAiB,MAAjB,EAAyB,IAAI,CAAC,IAA9B,CANA,CAAA;AAAA,QAOA,gBAAA,CAAiB,MAAjB,EAAyB,IAAI,CAAC,IAA9B,CAPA,CAAA;AAAA,QAQA,gBAAA,CAAiB,MAAjB,EAAyB,IAAI,CAAC,IAA9B,CARA,CAAA;AAAA,QASA,gBAAA,CAAiB,QAAjB,EAA2B,IAAI,CAAC,MAAhC,CATA,CAAA;AAAA,QAUA,gBAAA,CAAiB,OAAjB,EAA0B,IAAI,CAAC,KAA/B,CAVA,CAAA;AAAA,QAWA,IAAI,CAAC,cAAL,GAAsB,IAXtB,CAAA;eAYA,IAAI,CAAC,SAAL,GAAqB,IAAA,eAAA,CAAgB,IAAI,CAAC,OAArB,EAA8B,OAA9B,EAbvB;OADoB;IAAA,CAPtB;AAAA,IAuBA,KAAA,EAAO,SAAA,GAAA;AACL,MAAA,IAAG,IAAI,CAAC,OAAL,KAAgB,IAAnB;eACE,IAAI,CAAC,oBAAL,CAAA,EADF;OADK;IAAA,CAvBP;GADE,CAAJ,CAAA;AAAA","file":"peerjs-connector-polymer.js","sourceRoot":"/source/","sourcesContent":["\nnew Polymer 'peerjs-connector',\n join: (id)->\n idChanged: (old_val,new_val)->\n if this.is_initialized\n throw new Error \"You must not set the user_id twice!\"\n else\n this.initializeConnection() \n\n initializeConnection: ()-> \n if this.conn_id?\n console.log(\"now initializing\")\n options = {}\n writeIfAvailable = (name, value)->\n if value?\n options[name] = value\n writeIfAvailable 'key', this.key\n writeIfAvailable 'host', this.host\n writeIfAvailable 'port', this.port\n writeIfAvailable 'path', this.path\n writeIfAvailable 'secure', this.secure\n writeIfAvailable 'debug', this.debug\n this.is_initialized = true;\n this.connector = new PeerJsConnector this.conn_id, options\n \n ready: ()->\n if this.conn_id != null\n this.initializeConnection()\n \n"]}

File diff suppressed because one or more lines are too long