forked from socketstream/socketstream
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsocketstream.js
130 lines (94 loc) · 4.03 KB
/
socketstream.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SocketStream 0.3
// ----------------
require('colors');
var EventEmitter2 = require('eventemitter2').EventEmitter2;
// Get current version from package.json
var version = exports.version = require('./utils/file').loadPackageJSON().version;
// Set root path of your project
var root = exports.root = process.cwd().replace(/\\/g, '/'); // replace '\' with '/' to support Windows
// Warn if attempting to start without a cwd (e.g. through upstart script)
if (root == '/') throw new Error("You must change into the project directory before starting your SocketStream app")
// Set environment
var env = exports.env = (process.env['SS_ENV'] || 'development').toLowerCase();
// Session & Session Store
var session = exports.session = require('./session');
// Create an internal API object which is passed to sub-modules and can be used within your app
var api = exports.api = {
version: version,
root: root,
env: env,
log: console.log,
session: session,
// Call ss.api.add('name_of_api', value_or_function) from your app to safely extend the 'ss' internal API object passed through to your /server code
add: function(name, fn) {
var exists = false;
if (exists = api[name]) {
throw new Error("Unable to register internal API extension '" + name + "' as this name has already been taken");
} else {
api[name] = fn;
return true;
}
}
}
// Create internal Events bus
var events = exports.events = new EventEmitter2();
// Make sure nothing kills the server
//process.on('uncaughtException', function (err) { console.error('Exception caught: ', err)})
// Publish Events
var publish = exports.publish = require('./publish/index')();
// HTTP
var http = exports.http = require('./http/index')(root);
// Client Asset Manager
var client = exports.client = require('./client/index')(api, http.router);
// Allow other libs to send assets to the client
api.client = {send: client.assets.send};
// Incoming Request Responders
var responders = exports.responders = require('./request/index')(api);
// Websocket Layer (transport, message responders, transmit incoming events)
var ws = exports.ws = require('./websocket/index')(api, responders);
// Only one instance of the server can be started at once
var serverInstance = null;
// Public API
var start = function(httpServer) {
// Load SocketStream server instance
var server = {
responders: responders.load(),
eventTransport: publish.transport.load(),
sessionStore: session.store.get()
};
// Extend the internal API with a publish object you can call from your own server-side code
api.publish = publish.api(server.eventTransport);
// Start web stack
if (httpServer) {
console.log('Starting SocketStream %s in %s mode...'.green, version, env);
// Bind responders to websocket
ws.load(httpServer, server.responders, server.eventTransport);
// Append SocketStream middleware to stack
http.load(client.options.dirs.static, server.sessionStore, session.options);
// Load Client Asset Manager
client.load(api);
// Send server instance to any registered modules (e.g. console)
events.emit('server:start', server);
// If no HTTP server is passed return an API to allow for server-side testing
// Note this feature is currently considered 'experiemntal' and the implementation
// may change in the future to ensure any type of Request Responder can be tested
} else {
var sessionID = session.create();
for (id in server.responders) {
var responder = server.responders[id];
if (responder.name && responder.interfaces.internal) {
var fn = function(){
var args = Array.prototype.slice.call(arguments);
var cb = args.pop();
return responder.interfaces.internal(args, {sessionId: sessionID, transport: 'test'}, function(err, params){ cb(params) });
}
api.add(responder.name, fn);
}
}
}
return api;
}
// Ensure server can only be started once
exports.start = function(httpServer) {
return serverInstance || (serverInstance = start(httpServer));
}