Skip to content

Commit 6a87857

Browse files
committed
feat(gen): replace socket.io w/ primus + uws
#2565
1 parent f69f560 commit 6a87857

File tree

20 files changed

+164
-136
lines changed

20 files changed

+164
-136
lines changed

Diff for: Gruntfile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ module.exports = function (grunt) {
112112
testing: 'jasmine',
113113
auth: true,
114114
oauth: ['googleAuth', 'twitterAuth'],
115-
socketio: true
115+
ws: true
116116
};
117117

118118
var deps = [

Diff for: docs/01_Getting_Started/04_Project_Overview.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ webpack.make.js // main file for Webpack configuration
111111
│ local.env.js // ignored by Git
112112
│ local.env.sample.js // sensitive environment variables are stored here, and added at server start. Copy to `local.env.js`.
113113
│ seed.js // re-seeds database with fresh data
114-
socketio.js // Socket IO configuration / imports
114+
websockets.js // WebSocket configuration / imports
115115
116116
└───environment
117117
development.js

Diff for: src/generators/app/index.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -270,14 +270,14 @@ export class Generator extends Base {
270270
}]
271271
}, {
272272
type: 'confirm',
273-
name: 'socketio',
274-
message: 'Would you like to use socket.io?',
273+
name: 'ws',
274+
message: 'Would you like to use WebSockets?',
275275
// to-do: should not be dependent on ODMs
276276
when: answers => answers.odms && answers.odms.length !== 0,
277277
default: true
278278
}]).then(answers => {
279-
if(answers.socketio) this.filters.socketio = true;
280-
insight.track('socketio', !!answers.socketio);
279+
if(answers.ws) this.filters.ws = true;
280+
insight.track('ws', !!answers.ws);
281281

282282
if(answers.auth) this.filters.auth = true;
283283
insight.track('auth', !!answers.auth);
@@ -374,7 +374,7 @@ export class Generator extends Base {
374374
this.config.set('pluralizeRoutes', true);
375375

376376
this.config.set('insertSockets', true);
377-
this.config.set('registerSocketsFile', 'server/config/socketio.js');
377+
this.config.set('registerSocketsFile', 'server/config/websockets.js');
378378
this.config.set('socketsNeedle', '// Insert sockets below');
379379

380380
this.config.set('insertModels', true);

Diff for: src/generators/endpoint/index.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export class Generator extends NamedBase {
9797
end() {
9898
if(this.config.get('insertRoutes')) {
9999
var routesFile = this.config.get('registerRoutesFile');
100-
var reqPath = this.relativeRequire(this.routeDest, routesFile);
100+
let reqPath = this.relativeRequire(this.routeDest, routesFile);
101101
var routeConfig = {
102102
file: routesFile,
103103
needle: this.config.get('routesNeedle'),
@@ -108,23 +108,22 @@ export class Generator extends NamedBase {
108108
this.rewriteFile(routeConfig);
109109
}
110110

111-
if(this.filters.socketio && this.config.get('insertSockets')) {
111+
if(this.filters.ws && this.config.get('insertSockets')) {
112112
var socketsFile = this.config.get('registerSocketsFile');
113-
var reqPath = this.relativeRequire(this.routeDest + '/' + this.basename +
114-
'.socket', socketsFile);
113+
let reqPath = this.relativeRequire(this.routeDest + '/' + this.basename + '.socket', socketsFile);
115114
var socketConfig = {
116115
file: socketsFile,
117116
needle: this.config.get('socketsNeedle'),
118117
splicable: [
119-
`require('${reqPath}').register(socket);`
118+
`require('${reqPath}').register,`
120119
]
121120
};
122121
this.rewriteFile(socketConfig);
123122
}
124123

125124
if(this.filters.sequelize && this.config.get('insertModels')) {
126125
var modelsFile = this.config.get('registerModelsFile');
127-
var reqPath = this.relativeRequire(`${this.routeDest}/${this.basename}.model`, modelsFile);
126+
let reqPath = this.relativeRequire(`${this.routeDest}/${this.basename}.model`, modelsFile);
128127
var modelConfig = {
129128
file: modelsFile,
130129
needle: this.config.get('modelsNeedle'),

Diff for: src/test/endpoint.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const defaultOptions = {
3030
odms: ['mongoose'],
3131
auth: true,
3232
oauth: [],
33-
socketio: true
33+
ws: true
3434
};
3535

3636
function runEndpointGen(name, opt={}) {

Diff for: src/test/fixtures/.yo-rc.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"routesBase": "/api/",
88
"pluralizeRoutes": true,
99
"insertSockets": true,
10-
"registerSocketsFile": "server/config/socketio.js",
10+
"registerSocketsFile": "server/config/websockets.js",
1111
"socketsNeedle": "// Insert sockets below",
1212
"insertModels": true,
1313
"registerModelsFile": "server/sqldb/index.js",
@@ -21,7 +21,7 @@
2121
"uirouter": true,
2222
"bootstrap": true,
2323
"uibootstrap": true,
24-
"socketio": true,
24+
"ws": true,
2525
"auth": true,
2626
"models": true,
2727
"mongooseModels": true,

Diff for: src/test/get-expected-files.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -203,18 +203,18 @@ export function app(options) {
203203
'client/components/oauth-buttons/oauth-buttons.' + stylesheet,
204204
'client/components/oauth-buttons/oauth-buttons.' + markup,
205205
'client/components/oauth-buttons/oauth-buttons.component.' + script,
206-
'client/components/oauth-buttons/oauth-buttons.component.spec.' + script,
206+
'client/components/oauth-buttons/oauth-buttons.component.spec.' + script,
207207
'e2e/components/oauth-buttons/oauth-buttons.po.js'
208208
]);
209209
}
210210

211-
/* Socket.IO */
212-
if (options.socketio) {
211+
/* WebSockets */
212+
if (options.ws) {
213213
files = files.concat([
214214
'client/components/socket/socket.service.' + script,
215215
'client/components/socket/socket.mock.' + script,
216216
'server/api/thing/thing.socket.js',
217-
'server/config/socketio.js'
217+
'server/config/websockets.js'
218218
]);
219219
}
220220

Diff for: src/test/main.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const defaultOptions = {
2727
odms: ['mongoose'],
2828
auth: true,
2929
oauth: [],
30-
socketio: true
30+
ws: true
3131
};
3232
const TEST_DIR = __dirname;
3333

@@ -198,7 +198,7 @@ describe('angular-fullstack:app', function() {
198198
odms: ['mongoose'],
199199
auth: true,
200200
oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'],
201-
socketio: true,
201+
ws: true,
202202
bootstrap: true,
203203
uibootstrap: true
204204
};
@@ -270,7 +270,7 @@ describe('angular-fullstack:app', function() {
270270
odms: ['sequelize'],
271271
auth: true,
272272
oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'],
273-
socketio: true,
273+
ws: true,
274274
bootstrap: true,
275275
uibootstrap: true
276276
};
@@ -343,7 +343,7 @@ describe('angular-fullstack:app', function() {
343343
odms: [],
344344
auth: false,
345345
oauth: [],
346-
socketio: false,
346+
ws: false,
347347
bootstrap: false,
348348
uibootstrap: false
349349
};

Diff for: templates/app/_package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@
4141
"passport-local": "^1.0.0",<% } %><% if(filters.facebookAuth) { %>
4242
"passport-facebook": "^2.0.0",<% } %><% if(filters.twitterAuth) { %>
4343
"passport-twitter": "^1.0.3",<% } %><% if(filters.googleAuth) { %>
44-
"passport-google-oauth20": "^1.0.0",<% } %><% if(filters.socketio) { %>
45-
"socket.io": "^1.3.5",
46-
"socket.io-client": "^1.3.5",
47-
"socketio-jwt": "^4.2.0",<% } %>
44+
"passport-google-oauth20": "^1.0.0",<% } %><% if(filters.ws) { %>
45+
"primus": "^7.0.1",
46+
"primus-emit": "^1.0.0",
47+
"uws": "^0.14.5",<% } %>
4848
"serve-favicon": "^2.3.0",
4949
"shrink-ray": "^0.1.3"
5050
},

Diff for: templates/app/client/app/main/main.component.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, OnInit<% if(filters.socketio) { %>, OnDestroy<% } %> } from '@angular/core';
1+
import { Component, OnInit<% if(filters.ws) { %>, OnDestroy<% } %> } from '@angular/core';
22
import { Http } from '@angular/http';
33
import { Observable } from 'rxjs/Observable';
44
import { SocketService } from '../../components/socket/socket.service';
@@ -8,34 +8,34 @@ import { SocketService } from '../../components/socket/socket.service';
88
template: require('./main.<%=templateExt%>'),
99
styles: [require('./main.<%=styleExt%>')],
1010
})
11-
export class MainComponent implements OnInit<% if(filters.socketio) { %>, OnDestroy<% } %> {
12-
<%_ if(filters.socketio) { -%>
11+
export class MainComponent implements OnInit<% if(filters.ws) { %>, OnDestroy<% } %> {
12+
<%_ if(filters.ws) { -%>
1313
SocketService;<% } %>
1414
awesomeThings = [];
1515
<%_ if(filters.models) { -%>
1616
newThing = '';<% } %>
1717

1818
<%_ if(filters.babel) { -%>
1919
static parameters = [Http, SocketService];<% } %>
20-
constructor(<%= private() %>http: Http<% if(filters.socketio) { %>, <%= private() %>socketService: SocketService<% } %>) {
20+
constructor(<%= private() %>http: Http<% if(filters.ws) { %>, <%= private() %>socketService: SocketService<% } %>) {
2121
this.Http = http;
22-
<%_ if(filters.socketio) { -%>
22+
<%_ if(filters.ws) { -%>
2323
this.SocketService = socketService;<% } %>
2424
}
2525

2626
ngOnInit() {
2727
this.Http.get('/api/things')
2828
.map(res => {
2929
return res.json();
30-
<%_ if(filters.socketio) { -%>
31-
// this.SocketService.syncUpdates('thing', this.awesomeThings);<% } %>
3230
})
3331
.catch(err => Observable.throw(err.json().error || 'Server error'))
3432
.subscribe(things => {
3533
this.awesomeThings = things;
34+
<%_ if(filters.ws) { -%>
35+
this.SocketService.syncUpdates('thing', this.awesomeThings);<% } %>
3636
});
3737
}<% if (filters.models) { %>
38-
<%_ if(filters.socketio) { %>
38+
<%_ if(filters.ws) { %>
3939

4040
ngOnDestroy() {
4141
this.SocketService.unsyncUpdates('thing');
@@ -50,7 +50,7 @@ export class MainComponent implements OnInit<% if(filters.socketio) { %>, OnDest
5050
.map(res => res.json())
5151
.catch(err => Observable.throw(err.json().error || 'Server error'))
5252
.subscribe(thing => {
53-
this.awesomeThings.push(thing);
53+
console.log('Added Thing:', thing);
5454
});
5555
}
5656
}
@@ -60,7 +60,7 @@ export class MainComponent implements OnInit<% if(filters.socketio) { %>, OnDest
6060
.map(res => res.json())
6161
.catch(err => Observable.throw(err.json().error || 'Server error'))
6262
.subscribe(() => {
63-
this.awesomeThings.splice(this.awesomeThings.findIndex(el => el._id === thing._id), 1);
63+
console.log('Deleted Thing');
6464
});
6565
}<% } %>
6666
}

Diff for: templates/app/client/app/main/main.component.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe('Component: MainComponent', function() {
88
beforeEach(angular.mock.module(main));
99
<%_ if (filters.uirouter) { _%>
1010
beforeEach(angular.mock.module('stateMock'));<% } _%>
11-
<%_ if (filters.socketio) { _%>
11+
<%_ if (filters.ws) { _%>
1212
beforeEach(angular.mock.module('socketMock'));<% } %>
1313

1414
var scope;
@@ -22,7 +22,7 @@ describe('Component: MainComponent', function() {
2222
$http,
2323
$componentController,
2424
$rootScope<% if (filters.uirouter) {%>,
25-
$state<% } %><% if (filters.socketio) {%>,
25+
$state<% } %><% if (filters.ws) {%>,
2626
socket<% } %>) {
2727
$httpBackend = _$httpBackend_;
2828
$httpBackend.expectGET('/api/things')
@@ -32,7 +32,7 @@ describe('Component: MainComponent', function() {
3232
state = $state;<% } %>
3333
mainComponent = $componentController('main', {
3434
$http: $http,
35-
$scope: scope<% if (filters.socketio) {%>,
35+
$scope: scope<% if (filters.ws) {%>,
3636
socket: socket<% } %>
3737
});
3838
}));

Diff for: templates/app/client/app/main/main.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ <h1 class="page-header">Features:</h1>
1717
</a></li>
1818
</ul>
1919
</div>
20-
</div><% if (filters.socketio) { %>
20+
</div><% if (filters.ws) { %>
2121

2222
<form class="thing-form">
2323
<label>Syncs in realtime across clients</label>

Diff for: templates/app/client/app/main/main.module.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { RouterModule, Routes } from '@angular/router';<% } %>
99
import { TooltipModule } from 'ng2-bootstrap';<% } %>
1010

1111
import { MainComponent } from './main.component';
12-
<%_ if(filters.socketio) { -%>
12+
<%_ if(filters.ws) { -%>
1313
import { SocketService } from '../../components/socket/socket.service';<% } %>
1414

1515
<%_ if(filters.ngroute) { _%>
@@ -37,7 +37,7 @@ export const STATES = [
3737
declarations: [
3838
MainComponent,
3939
],
40-
<%_ if(filters.socketio) { -%>
40+
<%_ if(filters.ws) { -%>
4141
providers: [
4242
SocketService,
4343
],<% } %>

Diff for: templates/app/client/components/socket(socketio)/socket.service.js

+29-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
'use strict';
2+
import Primus from './primus';
3+
import primusEmit from 'primus-emit';
24
import { Injectable } from '@angular/core';
35
import { noop, find, remove } from 'lodash';
4-
import io from 'socket.io-client';
5-
import constants from '../../app/app.constants';
66

77
@Injectable()
88
export class SocketService {
9-
socket;
9+
primus;
1010

1111
constructor() {
12-
this.socket = io(constants.env === 'development' ? `localhost:${constants.port}` : '', {
13-
// Send auth token on connection, you will need to DI the Auth service above
14-
// 'query': 'token=' + Auth.getToken()
12+
const primus = Primus.connect();
13+
primus.plugin('emit', primusEmit);
14+
15+
primus.on('open', function open() {
16+
console.log('Connection opened');
17+
});
18+
19+
if(process.env.NODE_ENV === 'development') {
20+
primus.on('data', function message(data) {
21+
console.log('Socket:', data);
22+
});
23+
}
24+
25+
primus.on('info', data => {
26+
console.log('info:', data);
1527
});
28+
29+
this.primus = primus;
1630
}
1731

1832
/**
@@ -29,10 +43,11 @@ export class SocketService {
2943
/**
3044
* Syncs item creation/updates on 'model:save'
3145
*/
32-
this.socket.on(`${modelName}:save`, function(item) {
33-
var oldItem = find(array, {_id: item._id});
34-
var index = array.indexOf(oldItem);
35-
var event = 'created';
46+
this.primus.on(`${modelName}:save`, item => {
47+
console.log(item);
48+
let oldItem = find(array, {_id: item._id});
49+
let index = array.indexOf(oldItem);
50+
let event = 'created';
3651

3752
// replace oldItem if it exists
3853
// otherwise just add item to the collection
@@ -49,10 +64,9 @@ export class SocketService {
4964
/**
5065
* Syncs removed items on 'model:remove'
5166
*/
52-
this.socket.on(`${modelName}:remove`, function(item) {
53-
var event = 'deleted';
67+
this.primus.on(`${modelName}:remove`, item => {
5468
remove(array, {_id: item._id});
55-
cb(event, item, array);
69+
cb('deleted', item, array);
5670
});
5771
}
5872

@@ -62,7 +76,7 @@ export class SocketService {
6276
* @param modelName
6377
*/
6478
unsyncUpdates(modelName) {
65-
this.socket.removeAllListeners(`${modelName}:save`);
66-
this.socket.removeAllListeners(`${modelName}:remove`);
79+
this.primus.removeAllListeners(`${modelName}:save`);
80+
this.primus.removeAllListeners(`${modelName}:remove`);
6781
}
6882
}

0 commit comments

Comments
 (0)