Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
language: node_js
node_js:
- "0.10"
- "0.8"
- "0.8"
# - "0.11"
43 changes: 43 additions & 0 deletions documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,47 @@ app.configure(feathers.socketio(function(io) {

Once the server has been started with `app.listen()` the SocketIO object is available as `app.io`.

### Primus

[Primus](https://github.com/primus/primus) is a universal wrapper for real-time frameworks and allows you to transparently use Engine.IO, WebSockets, BrowserChannel, SockJS and Socket.IO. Set it up with `feathers.primus(configuration [, fn])` where `configuration` is the [Primus server configuration](https://github.com/primus/primus#getting-started) and `fn` an optional callback with the Primus server instance that can e.g. be used for setting up [authorization](https://github.com/primus/primus#authorization):

```js
// Set up Primus with SockJS
app.configure(feathers.primus({
transformer: 'sockjs'
}, function(primus) {
// Set up Primus authorization here
primus.authorize(function (req, done) {
var auth;

try { auth = authParser(req.headers['authorization']) }
catch (ex) { return done(ex) }

// Do some async auth check
authCheck(auth, done);
});
}));
```

In the Browser you can connect like this:

```html
<script type="text/javascript" src="primus/primus.js"></script>
<script type="text/javascript">
var primus = new Primus(url);

primus.on('todos created', function(todo) {
console.log('Someone created a Todo', todo);
});

primus.send('todos::create', { description: 'Do something', {}, function() {
primus.send('todos::find', {}, function(error, todos) {
console.log(todos);
});
});
</script>
```

## API

### listen
Expand Down Expand Up @@ -453,6 +494,8 @@ With that being said there are some amazing frameworks already out there and we

__0.3.0__

- Added [Primus](https://github.com/primus/primus) provider ([#34](https://github.com/feathersjs/feathers/pull/34))
- `app.setup(server)` to support HTTPS (and other functionality that requires a custom server) ([#33](https://github.com/feathersjs/feathers/pull/33))
- Removed bad SocketIO configuration ([#19](https://github.com/feathersjs/feathers/issues/19))
- Add .npmignore to not publish .idea folder ([#30](https://github.com/feathersjs/feathers/issues/30))
- Remove middleware: connect.bodyParser() ([#27](https://github.com/feathersjs/feathers/pull/27))
Expand Down
3 changes: 2 additions & 1 deletion lib/providers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

module.exports = {
rest: require('./rest'),
socketio: require('./socketio')
socketio: require('./socketio'),
primus: require('./primus')
};
64 changes: 64 additions & 0 deletions lib/providers/primus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
'use strict';

var _ = require('underscore');
var Proto = require('uberproto');
var Primus = require('primus');
var Emitter = require('primus-emitter');

module.exports = function(config, configurer) {
return function() {
var app = this;
var services = {};

app.enable('feathers primus');

// Monkey patch app.setup(server)
Proto.mixin({
setup: function(server) {
var self = this;
var result = this._super.apply(this, arguments);

if (this.disabled('feathers primus')) {
return result;
}

var primus = this.primus = new Primus(server, config);
primus.use('emitter', Emitter);

_.each(services, function(service, path) {
// If the service emits events that we want to listen to (Event mixin)
if (typeof service.on === 'function' && service._serviceEvents) {
_.each(service._serviceEvents, function(ev) {
service.on(ev, function(data) {
primus.forEach(function (spark) {
spark.send(path + ' ' + ev, data);
});
});
});
}
});

primus.on('connection', function(spark) {
_.each(services, function(service, path) {
_.each(self.methods, function(method) {
var name = path + '::' + method;
if (service[method]) {
spark.on(name, service[method].bind(service));
}
});
});
});

if (typeof configurer === 'function') {
configurer.call(this, primus);
}

return result;
}
}, app);

app.providers.push(function(path, service) {
services[path] = service;
});
};
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
"express": "~ 3.4.0",
"rubberduck": "~1.x",
"underscore": "~1.5.0",
"socket.io": "~0.9.0"
"socket.io": "~0.9.0",
"primus-emitter": "~2.0.5",
"primus": "~1.5.1"
},
"devDependencies": {
"request": "~2.21.0",
Expand Down
113 changes: 113 additions & 0 deletions test/providers/primus.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use strict';

var feathers = require('../../lib/feathers');
var fixture = require('./service-fixture');
var todoService = fixture.Service;
var verify = fixture.verify;

describe('Primus provider', function () {
var server, socket;

before(function () {
server = feathers()
.configure(feathers.primus({
transformer: 'socket.io'
}, function(primus) {
socket = new primus.Socket('http://localhost:7888');
}))
.use('todo', todoService)
.listen(7888);
});

after(function (done) {
socket.socket.disconnect();
server.close(done);
});

describe('CRUD', function () {
it('::find', function (done) {
socket.send('todo::find', {}, function (error, data) {
verify.find(data);

done(error);
});
});

it('::get', function (done) {
socket.send('todo::get', 'laundry', {}, function (error, data) {
verify.get('laundry', data);

done(error);
});
});

it('::create', function (done) {
var original = {
name: 'creating'
};

socket.send('todo::create', original, {}, function (error, data) {
verify.create(original, data);

done(error);
});
});

it('::update', function (done) {
var original = {
name: 'updating'
};

socket.send('todo::update', 23, original, {}, function (error, data) {
verify.update(23, original, data);

done(error);
});
});

it('::remove', function (done) {
socket.send('todo::remove', 11, {}, function (error, data) {
verify.remove(11, data);

done(error);
});
});
});

describe('Events', function () {
it('created', function (done) {
var original = {
name: 'created event'
};

socket.on('todo created', function (data) {
verify.create(original, data);
done();
});

socket.send('todo::create', original, {}, function () {});
});

it('updated', function (done) {
var original = {
name: 'updated event'
};

socket.on('todo updated', function (data) {
verify.update(10, original, data);
done();
});

socket.send('todo::update', 10, original, {}, function () {});
});

it('removed', function (done) {
socket.on('todo removed', function (data) {
verify.remove(333, data);
done();
});

socket.send('todo::remove', 333, {}, function () {});
});
});
});