Skip to content
Open
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
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: node_js
node_js:
- 0.8
- 0.10
52 changes: 34 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# PeerJS Server: Server component for PeerJS #
[![Build Status](https://travis-ci.org/peers/peerjs-server.png?branch=master)](https://travis-ci.org/peers/peerjs-server)

# PeerServer: A server for PeerJS #

PeerServer helps broker connections between PeerJS clients. Data is not proxied through the server.

Expand All @@ -12,32 +14,46 @@ PeerServer helps broker connections between PeerJS clients. Data is not proxied

Install the library:

npm install peer
```bash
$> npm install peer
```

Run the server:

var PeerServer = require('peer').PeerServer;
var server = new PeerServer({ port: 9000 });
```bash
$> peerjs --port 9000 --key peerjs
```

Or, create a custom server:

```javascript
var PeerServer = require('peer').PeerServer;
var server = new PeerServer({ port: 9000 });
```

Connecting to the server from PeerJS:

<script>
// No API key required when not using cloud server
var peer = new Peer('someid', {host: 'localhost', port: 9000});
</script>
```html
<script>
// No API key required when not using cloud server
var peer = new Peer('someid', {host: 'localhost', port: 9000});
</script>
```

Using HTTPS: Simply pass in PEM-encoded certificate and key.

var fs = require('fs');
var PeerServer = require('peer').PeerServer;

var server = new PeerServer({
port: 9000,
ssl: {
key: fs.readFileSync('/path/to/your/ssl/key/here.key'),
certificate: fs.readFileSync('/path/to/your/ssl/certificate/here.crt')
}
});
```javascript
var fs = require('fs');
var PeerServer = require('peer').PeerServer;

var server = new PeerServer({
port: 9000,
ssl: {
key: fs.readFileSync('/path/to/your/ssl/key/here.key'),
certificate: fs.readFileSync('/path/to/your/ssl/certificate/here.crt')
}
});
```

## Problems?

Expand Down
71 changes: 71 additions & 0 deletions bin/peerjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env node

var path = require('path')
, pkg = require('../package.json')
, fs = require('fs')
, version = pkg.version
, PeerServer = require('../lib/server').PeerServer
, opts = require('optimist')
.usage('Usage: $0')
.options({
debug: {
demand: false,
alias: 'd',
description: 'debug',
default: false
},
timeout: {
demand: false,
alias: 't',
description: 'timeout (milliseconds)',
default: 5000
},
ip_limit: {
demand: false,
alias: 'i',
description: 'IP limit',
default: 5000
},
concurrent_limit: {
demand: false,
alias: 'c',
description: 'concurrent limit',
default: 5000
},
key: {
demand: false,
alias: 'k',
description: 'connection key',
default: 'peerjs'
},
sslkey: {
demand: false,
description: 'path to SSL key'
},
sslcert: {
demand: false,
description: 'path to SSL certificate'
},
port: {
demand: true,
alias: 'p',
description: 'port',
}
}).argv;

opts.version = version;

if (opts.sslkey && opts.sslcert) {
opts['ssl'] = {};
opts.ssl['key'] = fs.readFileSync(path.resolve(opts.sslkey));
opts.ssl['certificate'] = fs.readFileSync(path.resolve(opts.sslcert));
}

process.on('uncaughtException', function(e) {
console.error('Error: ' + e);
});

var server = new PeerServer(opts);
console.log(
"Started PeerServer, port: " + opts.port + (" (v. %s)"), version
);
53 changes: 19 additions & 34 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ function PeerServer(options) {

util.debug = this._options.debug;

// Set up HTTPS server if key and certificate are provided.
var secure = this._options.ssl.key && this._options.ssl.certificate;
// Print warning if only one of the two is given.
if (Object.keys(this._options.ssl).length === 1) {
util.prettyError('Warning: PeerServer will not run on an HTTPS server'
Expand All @@ -49,7 +47,7 @@ function PeerServer(options) {
this._ips = {};

this._setCleanupIntervals();
};
}

util.inherits(PeerServer, EventEmitter);

Expand All @@ -73,7 +71,7 @@ PeerServer.prototype._initializeWSS = function() {
socket.close();
return;
}

if (!self._clients[key] || !self._clients[key][id]) {
self._checkKey(key, ip, function(err) {
if (!err) {
Expand Down Expand Up @@ -126,35 +124,22 @@ PeerServer.prototype._configureWS = function(socket, key, id, token) {
try {
var message = JSON.parse(data);

switch (message.type) {
case 'LEAVE':
// Clean up if a Peer sends a LEAVE.
if (!message.dst) {
self._removePeer(key, id);
break;
}
// ICE candidates
case 'CANDIDATE':
// Offer or answer between peers.
case 'OFFER':
case 'ANSWER':
// Use the ID we know to be correct to prevent spoofing.
self._handleTransmission(key, {
type: message.type,
src: id,
dst: message.dst,
payload: message.payload
});
break;
default:
util.prettyError('Message unrecognized');
if (['LEAVE', 'CANDIDATE', 'OFFER', 'ANSWER'].indexOf(message.type) !== -1) {
self._handleTransmission(key, {
type: message.type,
src: id,
dst: message.dst,
payload: message.payload
});
} else {
util.prettyError('Message unrecognized');
}
} catch(e) {
throw e;
util.log('Invalid message', data);
throw e;
}
});
}
};


PeerServer.prototype._checkKey = function(key, ip, cb) {
Expand All @@ -181,14 +166,14 @@ PeerServer.prototype._checkKey = function(key, ip, cb) {
} else {
cb('Invalid key provided');
}
}
};

/** Initialize HTTP server routes. */
PeerServer.prototype._initializeHTTP = function() {
var self = this;

this._app.use(restify.bodyParser({ mapParams: false }));
this._app.use(restify.queryParser())
this._app.use(restify.queryParser());
this._app.use(util.allowCrossDomain);

// Retrieve guaranteed random ID.
Expand All @@ -203,7 +188,7 @@ PeerServer.prototype._initializeHTTP = function() {
var id = req.params.id;
var token = req.params.token;
var key = req.params.key;
var ip = req.ip;
var ip = req.connection.remoteAddress;

if (!self._clients[key] || !self._clients[key][id]) {
self._checkKey(key, ip, function(err) {
Expand Down Expand Up @@ -307,7 +292,7 @@ PeerServer.prototype._pruneOutstanding = function() {
var keys = Object.keys(this._outstanding);
for (var k = 0, kk = keys.length; k < kk; k += 1) {
var key = keys[k];
var dsts = Object.keys(this._outstanding[key]);
var dsts = Object.keys(this._outstanding[key]);
for (var i = 0, ii = dsts.length; i < ii; i += 1) {
var offers = this._outstanding[key][dsts[i]];
var seen = {};
Expand All @@ -332,7 +317,7 @@ PeerServer.prototype._setCleanupIntervals = function() {
var keys = Object.keys(self._ips);
for (var i = 0, ii = keys.length; i < ii; i += 1) {
var key = keys[i];
if (self._ips[key] == 0) {
if (self._ips[key] === 0) {
delete self._ips[key];
}
}
Expand Down Expand Up @@ -383,7 +368,7 @@ PeerServer.prototype._handleTransmission = function(key, message) {
destination.res.write(data);
} else {
// Neither socket no res available. Peer dead?
throw "Peer dead"
throw "Peer dead";
}
} catch (e) {
// This happens when a peer disconnects without closing connections and
Expand Down
1 change: 1 addition & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var util = {
});
},
extend: function(dest, source) {
source = source || {};
for(var key in source) {
if(source.hasOwnProperty(key)) {
dest[key] = source[key];
Expand Down
17 changes: 15 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "peer",
"version": "0.1.6",
"version": "0.2.0",
"description": "Peer-to-peer data in browsers",
"main": "lib/server.js",
"bin": { "peerjs": "./bin/peerjs" },
"repository": {
"type": "git",
"url": "git://github.com/peers/peerjs-server.git"
Expand All @@ -11,6 +12,18 @@
"license": "MIT",
"dependencies": {
"restify": "~2.3.5",
"ws": "~0.4.25"
"ws": "~0.4.25",
"optimist": "*"
},
"devDependencies": {
"expect.js": "*",
"sinon": "*",
"mocha": "*"
},
"engines": {
"node": ">=0.8"
},
"scripts": {
"test": "mocha test"
}
}
Loading