@depup/primus 8.0.9-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +36 -0
- package/changes.json +30 -0
- package/dist/primus.js +3663 -0
- package/errors.js +51 -0
- package/index.js +1153 -0
- package/middleware/access-control.js +20 -0
- package/middleware/authorization.js +57 -0
- package/middleware/error.js +41 -0
- package/middleware/forwarded.js +18 -0
- package/middleware/no-cache.js +25 -0
- package/middleware/primus.js +47 -0
- package/middleware/spec.js +36 -0
- package/middleware/xss.js +28 -0
- package/package.json +140 -0
- package/parsers/binary.js +54 -0
- package/parsers/ejson.js +41 -0
- package/parsers/json.js +35 -0
- package/parsers/msgpack.js +55 -0
- package/parsers.json +12 -0
- package/primus.js +1158 -0
- package/spark.js +515 -0
- package/transformer.js +237 -0
- package/transformers/browserchannel/client.js +92 -0
- package/transformers/browserchannel/index.js +19 -0
- package/transformers/browserchannel/server.js +64 -0
- package/transformers/engine.io/README.md +34 -0
- package/transformers/engine.io/client.js +111 -0
- package/transformers/engine.io/index.js +15 -0
- package/transformers/engine.io/library.js +2273 -0
- package/transformers/engine.io/server.js +63 -0
- package/transformers/faye/client.js +103 -0
- package/transformers/faye/index.js +12 -0
- package/transformers/faye/server.js +85 -0
- package/transformers/sockjs/README.md +31 -0
- package/transformers/sockjs/client.js +86 -0
- package/transformers/sockjs/index.js +15 -0
- package/transformers/sockjs/library.js +4201 -0
- package/transformers/sockjs/server.js +108 -0
- package/transformers/uws/index.js +12 -0
- package/transformers/uws/server.js +131 -0
- package/transformers/websockets/client.js +112 -0
- package/transformers/websockets/index.js +12 -0
- package/transformers/websockets/server.js +77 -0
- package/transformers.json +26 -0
package/transformer.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var log = require('diagnostics')('primus:transformer')
|
|
4
|
+
, middlewareError = require('./middleware/error')
|
|
5
|
+
, url = require('url').parse
|
|
6
|
+
, Ultron = require('ultron')
|
|
7
|
+
, fuse = require('fusing');
|
|
8
|
+
|
|
9
|
+
function noop() {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Transformer skeleton
|
|
13
|
+
*
|
|
14
|
+
* @constructor
|
|
15
|
+
* @param {Primus} primus Reference to the Primus instance.
|
|
16
|
+
* @api public
|
|
17
|
+
*/
|
|
18
|
+
function Transformer(primus) {
|
|
19
|
+
this.fuse();
|
|
20
|
+
|
|
21
|
+
this.ultron = new Ultron(primus.server); // Handles listeners with ease.
|
|
22
|
+
this.Spark = primus.Spark; // Reference to the Spark constructor.
|
|
23
|
+
this.primus = primus; // Reference to the Primus instance.
|
|
24
|
+
this.service = null; // Stores the real-time service.
|
|
25
|
+
|
|
26
|
+
this.initialise();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fuse(Transformer, require('eventemitter3'));
|
|
30
|
+
|
|
31
|
+
//
|
|
32
|
+
// Simple logger shortcut.
|
|
33
|
+
//
|
|
34
|
+
Object.defineProperty(Transformer.prototype, 'logger', {
|
|
35
|
+
get: function logger() {
|
|
36
|
+
return {
|
|
37
|
+
error: this.primus.emits('log', 'error'), // Log error <line>.
|
|
38
|
+
warn: this.primus.emits('log', 'warn'), // Log warn <line>.
|
|
39
|
+
info: this.primus.emits('log', 'info'), // Log info <line>.
|
|
40
|
+
debug: this.primus.emits('log', 'debug'), // Log debug <line>.
|
|
41
|
+
log: this.primus.emits('log', 'log'), // Log log <line>.
|
|
42
|
+
plain: this.primus.emits('log', 'log') // Log log <line>.
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create the server and attach the appropriate event listeners.
|
|
49
|
+
*
|
|
50
|
+
* @api private
|
|
51
|
+
*/
|
|
52
|
+
Transformer.readable('initialise', function initialise() {
|
|
53
|
+
if (this.server) this.server();
|
|
54
|
+
|
|
55
|
+
var server = this.primus.server
|
|
56
|
+
, transformer = this;
|
|
57
|
+
|
|
58
|
+
server.listeners('request').forEach(function each(fn) {
|
|
59
|
+
log('found existing request handlers on the HTTP server, moving Primus as first');
|
|
60
|
+
transformer.on('previous::request', fn, server);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
server.listeners('upgrade').forEach(function each(fn) {
|
|
64
|
+
log('found existing upgrade handlers on the HTTP server, moving Primus as first');
|
|
65
|
+
transformer.on('previous::upgrade', fn, server);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
//
|
|
69
|
+
// Remove the old listeners as we want to be the first request handler for all
|
|
70
|
+
// events.
|
|
71
|
+
//
|
|
72
|
+
server.removeAllListeners('request');
|
|
73
|
+
server.removeAllListeners('upgrade');
|
|
74
|
+
|
|
75
|
+
//
|
|
76
|
+
// Emit a close event.
|
|
77
|
+
//
|
|
78
|
+
this.ultron.on('close', function close() {
|
|
79
|
+
log('the HTTP server is closing');
|
|
80
|
+
transformer.emit('close');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
//
|
|
84
|
+
// Start listening for incoming requests if we have a listener assigned to us.
|
|
85
|
+
//
|
|
86
|
+
if (this.listeners('request').length || this.listeners('previous::request').length) {
|
|
87
|
+
server.on('request', this.request.bind(this));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (this.listeners('upgrade').length || this.listeners('previous::upgrade').length) {
|
|
91
|
+
server.on('upgrade', this.upgrade.bind(this));
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Iterate all the middleware layers that we're set on our Primus instance.
|
|
97
|
+
*
|
|
98
|
+
* @param {String} type Either `http` or `upgrade`
|
|
99
|
+
* @param {Request} req HTTP request.
|
|
100
|
+
* @param {Response} res HTTP response.
|
|
101
|
+
* @param {Function} next Continuation callback.
|
|
102
|
+
* @api private
|
|
103
|
+
*/
|
|
104
|
+
Transformer.readable('forEach', function forEach(type, req, res, next) {
|
|
105
|
+
var transformer = this
|
|
106
|
+
, layers = transformer.primus.layers
|
|
107
|
+
, primus = transformer.primus;
|
|
108
|
+
|
|
109
|
+
req.query = req.uri.query || {};
|
|
110
|
+
|
|
111
|
+
//
|
|
112
|
+
// Add some silly HTTP properties for connect.js compatibility.
|
|
113
|
+
//
|
|
114
|
+
req.originalUrl = req.url;
|
|
115
|
+
|
|
116
|
+
if (!layers.length) {
|
|
117
|
+
next();
|
|
118
|
+
return transformer;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
//
|
|
122
|
+
// Async or sync call the middleware layer.
|
|
123
|
+
//
|
|
124
|
+
(function iterate(index) {
|
|
125
|
+
var layer = layers[index++];
|
|
126
|
+
|
|
127
|
+
if (!layer) return next();
|
|
128
|
+
if (!layer.enabled || layer.fn[type] === false) return iterate(index);
|
|
129
|
+
|
|
130
|
+
if (layer.length === 2) {
|
|
131
|
+
log('executing middleware (%s) synchronously', layer.name);
|
|
132
|
+
|
|
133
|
+
if (layer.fn.call(primus, req, res)) return;
|
|
134
|
+
return iterate(index);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
log('executing middleware (%s) asynchronously', layer.name);
|
|
138
|
+
layer.fn.call(primus, req, res, function done(err) {
|
|
139
|
+
if (err) return middlewareError(err, req, res);
|
|
140
|
+
|
|
141
|
+
iterate(index);
|
|
142
|
+
});
|
|
143
|
+
}(0));
|
|
144
|
+
|
|
145
|
+
return transformer;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Start listening for incoming requests and check if we need to forward them to
|
|
150
|
+
* the transformers.
|
|
151
|
+
*
|
|
152
|
+
* @param {Request} req HTTP request.
|
|
153
|
+
* @param {Response} res HTTP response.
|
|
154
|
+
* @api private
|
|
155
|
+
*/
|
|
156
|
+
Transformer.readable('request', function request(req, res) {
|
|
157
|
+
if (!this.test(req)) return this.emit('previous::request', req, res);
|
|
158
|
+
|
|
159
|
+
req.headers['primus::req::backup'] = req;
|
|
160
|
+
res.once('end', function gc() {
|
|
161
|
+
delete req.headers['primus::req::backup'];
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
//
|
|
165
|
+
// I want to see you're face when you're looking at the lines of code above
|
|
166
|
+
// while you think, WTF what is this shit, you mad bro!? Let me take a moment
|
|
167
|
+
// to explain this mad and sadness.
|
|
168
|
+
//
|
|
169
|
+
// There are some real-time transformers that do not give us access to the
|
|
170
|
+
// HTTP request that initiated their `socket` connection. They only give us
|
|
171
|
+
// access to the information that they think is useful, we're greedy, we want
|
|
172
|
+
// everything and let developers decide what they want to use instead and
|
|
173
|
+
// therefor want to expose this HTTP request on our `spark` object.
|
|
174
|
+
//
|
|
175
|
+
// The reason it's added to the headers is because it's currently the only
|
|
176
|
+
// field that is accessible through all transformers.
|
|
177
|
+
//
|
|
178
|
+
|
|
179
|
+
log('handling HTTP request for url: %s', req.url);
|
|
180
|
+
this.forEach('http', req, res, this.emits('request', req, res));
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Starting listening for incoming upgrade requests and check if we need to
|
|
185
|
+
* forward them to the transformers.
|
|
186
|
+
*
|
|
187
|
+
* @param {Request} req HTTP request.
|
|
188
|
+
* @param {Socket} socket Socket.
|
|
189
|
+
* @param {Buffer} head Buffered data.
|
|
190
|
+
* @api private
|
|
191
|
+
*/
|
|
192
|
+
Transformer.readable('upgrade', function upgrade(req, socket, head) {
|
|
193
|
+
if (!this.test(req)) return this.emit('previous::upgrade', req, socket, head);
|
|
194
|
+
|
|
195
|
+
//
|
|
196
|
+
// See Transformer#request for an explanation of this madness.
|
|
197
|
+
//
|
|
198
|
+
req.headers['primus::req::backup'] = req;
|
|
199
|
+
socket.once('end', function gc() {
|
|
200
|
+
delete req.headers['primus::req::backup'];
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
log('handling HTTP upgrade for url: %s', req.url);
|
|
204
|
+
|
|
205
|
+
//
|
|
206
|
+
// Add a listener for the `'error'` event before running middleware as there
|
|
207
|
+
// isn't a default one in Node.js >= 10. The socket is destroyed when an error
|
|
208
|
+
// occurs so there is no need to do anything.
|
|
209
|
+
//
|
|
210
|
+
socket.on('error', noop);
|
|
211
|
+
|
|
212
|
+
this.forEach('upgrade', req, socket, () => {
|
|
213
|
+
socket.removeListener('error', noop);
|
|
214
|
+
this.emit('upgrade', req, socket, head);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Check if we should accept this request.
|
|
220
|
+
*
|
|
221
|
+
* @param {Request} req HTTP Request.
|
|
222
|
+
* @returns {Boolean} Do we need to accept this request.
|
|
223
|
+
* @api private
|
|
224
|
+
*/
|
|
225
|
+
Transformer.readable('test', function test(req) {
|
|
226
|
+
req.uri = url(req.url, true);
|
|
227
|
+
|
|
228
|
+
var pathname = req.uri.pathname || '/'
|
|
229
|
+
, route = this.primus.pathname;
|
|
230
|
+
|
|
231
|
+
return pathname.slice(0, route.length) === route;
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
//
|
|
235
|
+
// Expose the transformer's skeleton.
|
|
236
|
+
//
|
|
237
|
+
module.exports = Transformer;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/*globals BCSocket*/
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Minimum viable BrowserChannel client. This function is stringified and added
|
|
6
|
+
* in our client-side library.
|
|
7
|
+
*
|
|
8
|
+
* @runat client
|
|
9
|
+
* @api private
|
|
10
|
+
*/
|
|
11
|
+
module.exports = function client() {
|
|
12
|
+
var primus = this
|
|
13
|
+
, socket;
|
|
14
|
+
|
|
15
|
+
//
|
|
16
|
+
// Select an available BrowserChannel factory.
|
|
17
|
+
//
|
|
18
|
+
var Factory = (function factory() {
|
|
19
|
+
if ('undefined' !== typeof BCSocket) return BCSocket;
|
|
20
|
+
|
|
21
|
+
try { return Primus.requires('browserchannel').BCSocket; }
|
|
22
|
+
catch (e) {}
|
|
23
|
+
|
|
24
|
+
return undefined;
|
|
25
|
+
})();
|
|
26
|
+
|
|
27
|
+
if (!Factory) return primus.critical(new Error(
|
|
28
|
+
'Missing required `browserchannel` module. ' +
|
|
29
|
+
'Please run `npm install --save browserchannel`'
|
|
30
|
+
));
|
|
31
|
+
|
|
32
|
+
//
|
|
33
|
+
// Connect to the given URL.
|
|
34
|
+
//
|
|
35
|
+
primus.on('outgoing::open', function connect() {
|
|
36
|
+
primus.emit('outgoing::end');
|
|
37
|
+
|
|
38
|
+
var url = primus.uri({ protocol: 'http:' });
|
|
39
|
+
|
|
40
|
+
primus.socket = socket = new Factory(url, primus.merge(primus.transport, {
|
|
41
|
+
extraParams: primus.querystring(primus.url.query),
|
|
42
|
+
reconnect: false
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
//
|
|
46
|
+
// Setup the Event handlers.
|
|
47
|
+
//
|
|
48
|
+
socket.onopen = primus.emits('incoming::open');
|
|
49
|
+
socket.onerror = primus.emits('incoming::error');
|
|
50
|
+
socket.onclose = primus.emits('incoming::end');
|
|
51
|
+
socket.onmessage = primus.emits('incoming::data', function parse(next, evt) {
|
|
52
|
+
next(undefined, evt.data);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
//
|
|
57
|
+
// We need to write a new message to the socket.
|
|
58
|
+
//
|
|
59
|
+
primus.on('outgoing::data', function write(message) {
|
|
60
|
+
if (socket) socket.send(message);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
//
|
|
64
|
+
// Attempt to reconnect the socket.
|
|
65
|
+
//
|
|
66
|
+
primus.on('outgoing::reconnect', function reconnect() {
|
|
67
|
+
primus.emit('outgoing::open');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
//
|
|
71
|
+
// We need to close the socket.
|
|
72
|
+
//
|
|
73
|
+
primus.on('outgoing::end', function close() {
|
|
74
|
+
if (!socket) return;
|
|
75
|
+
|
|
76
|
+
socket.onerror = socket.onopen = socket.onclose = socket.onmessage = function () {};
|
|
77
|
+
|
|
78
|
+
//
|
|
79
|
+
// Bug: BrowserChannel cannot close the connection if it's already
|
|
80
|
+
// connecting. Bypass this behaviour by checking the readyState and
|
|
81
|
+
// defer the close call.
|
|
82
|
+
//
|
|
83
|
+
if (socket.readyState === socket.CONNECTING) {
|
|
84
|
+
socket.onopen = function onopen() {
|
|
85
|
+
this.close();
|
|
86
|
+
};
|
|
87
|
+
} else {
|
|
88
|
+
socket.close();
|
|
89
|
+
}
|
|
90
|
+
socket = null;
|
|
91
|
+
});
|
|
92
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('path')
|
|
4
|
+
, directory = require.resolve('browserchannel')
|
|
5
|
+
, library = path.join(path.dirname(directory), 'dist/bcsocket-uncompressed.js');
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
// Expose the module as new Transformer instance.
|
|
9
|
+
//
|
|
10
|
+
module.exports = require('../../transformer').extend({
|
|
11
|
+
// Creating a new real-time server.
|
|
12
|
+
server: require('./server'),
|
|
13
|
+
|
|
14
|
+
// The client-logic to connect with the a server.
|
|
15
|
+
client: require('./client'),
|
|
16
|
+
|
|
17
|
+
// The client-side library of the browserchannel.
|
|
18
|
+
library: require('fs').readFileSync(library, 'utf-8')
|
|
19
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var browserchannel = require('browserchannel')
|
|
4
|
+
, http = require('http');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Minimum viable BrowserChannel server for Node.js that works through the
|
|
8
|
+
* primus interface.
|
|
9
|
+
*
|
|
10
|
+
* @runat server
|
|
11
|
+
* @api private
|
|
12
|
+
*/
|
|
13
|
+
module.exports = function server() {
|
|
14
|
+
var primus = this.primus
|
|
15
|
+
, Spark = this.Spark;
|
|
16
|
+
|
|
17
|
+
//
|
|
18
|
+
// We've received a new connection, create a new Spark. The Spark will
|
|
19
|
+
// automatically announce it self as a new connection once it's created (after
|
|
20
|
+
// the next tick).
|
|
21
|
+
//
|
|
22
|
+
this.service = browserchannel.server(Object.assign(primus.options.transport, {
|
|
23
|
+
base: primus.pathname
|
|
24
|
+
}), function connection(socket) {
|
|
25
|
+
var spark = new Spark(
|
|
26
|
+
socket.headers // HTTP request headers.
|
|
27
|
+
, { // IP address Location.
|
|
28
|
+
remoteAddress: socket.address,
|
|
29
|
+
remotePort: 1337
|
|
30
|
+
}
|
|
31
|
+
, socket.query // Optional query string.
|
|
32
|
+
, socket.id // Unique connection id.
|
|
33
|
+
, null // We don't have have a HTTP request.
|
|
34
|
+
, socket // Reference to the BrowserChannel socket.
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
spark.on('outgoing::end', function end() {
|
|
38
|
+
if (socket) socket.stop();
|
|
39
|
+
}).on('outgoing::data', function write(data) {
|
|
40
|
+
socket.send(data);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
socket.on('message', spark.emits('incoming::data'));
|
|
44
|
+
socket.on('error', spark.emits('incoming::error'));
|
|
45
|
+
socket.on('close', spark.emits('incoming::end', function parser(next) {
|
|
46
|
+
socket.removeAllListeners();
|
|
47
|
+
socket = null;
|
|
48
|
+
next();
|
|
49
|
+
}));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
//
|
|
53
|
+
// Listen to upgrade requests.
|
|
54
|
+
//
|
|
55
|
+
this.on('request', function request(req, res) {
|
|
56
|
+
//
|
|
57
|
+
// The browser.channel returns a middleware layer.
|
|
58
|
+
//
|
|
59
|
+
this.service(req, res, function next() {
|
|
60
|
+
res.writeHead(404, {'content-type': 'text/plain'});
|
|
61
|
+
res.end(http.STATUS_CODES[404]);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Transformer: Engine.IO
|
|
2
|
+
|
|
3
|
+
A transformer abstraction for the Engine.IO framework. To enable this
|
|
4
|
+
transformer inside of `Primus` you need to add `engine.io` to your package.json:
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
npm install engine.io --save
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
And tell primus to use `engine.io` as transformer.
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
var Primus = require('primus');
|
|
14
|
+
|
|
15
|
+
var primus = new Primus(server, { transformer: 'engine.io' });
|
|
16
|
+
|
|
17
|
+
primus.on('connection', function connection(spark) {
|
|
18
|
+
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
# Compiling the Engine.IO library
|
|
23
|
+
|
|
24
|
+
We cannot depend on the `engine.io.js` file because it uses a UMD wrapper
|
|
25
|
+
that doesn't work with Primus when using RequireJS. To compile the
|
|
26
|
+
`engine.io-client` correctly use the `update.sh` utility which will build the
|
|
27
|
+
library and expose it as a property of the global object.
|
|
28
|
+
The steps required are the following:
|
|
29
|
+
|
|
30
|
+
1. Fork or clone Primus
|
|
31
|
+
2. cd in the directory and run `npm install`
|
|
32
|
+
3. cd in the directory `transformers/engine.io/` and run `./update.sh`
|
|
33
|
+
4. Commit the changes to the Primus main repository
|
|
34
|
+
5. Profit
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/*globals eio*/
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Minimum viable Engine.IO client. This function is stringified and added in
|
|
6
|
+
* our client-side library.
|
|
7
|
+
*
|
|
8
|
+
* @runat client
|
|
9
|
+
* @api private
|
|
10
|
+
*/
|
|
11
|
+
module.exports = function client() {
|
|
12
|
+
var onmessage = this.emits('incoming::data')
|
|
13
|
+
, onerror = this.emits('incoming::error')
|
|
14
|
+
, onopen = this.emits('incoming::open')
|
|
15
|
+
, onclose = this.emits('incoming::end')
|
|
16
|
+
, primus = this
|
|
17
|
+
, socket;
|
|
18
|
+
|
|
19
|
+
//
|
|
20
|
+
// Select an available Engine.IO factory.
|
|
21
|
+
//
|
|
22
|
+
var factory = (function factory() {
|
|
23
|
+
if ('undefined' !== typeof eio) return eio;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
var Socket = Primus.requires('engine.io-client').Socket;
|
|
27
|
+
|
|
28
|
+
return function eio(options) {
|
|
29
|
+
return new Socket(options);
|
|
30
|
+
}
|
|
31
|
+
} catch (e) {}
|
|
32
|
+
|
|
33
|
+
return undefined;
|
|
34
|
+
})();
|
|
35
|
+
|
|
36
|
+
if (!factory) return primus.critical(new Error(
|
|
37
|
+
'Missing required `engine.io-client` module. ' +
|
|
38
|
+
'Please run `npm install --save engine.io-client`'
|
|
39
|
+
));
|
|
40
|
+
|
|
41
|
+
//
|
|
42
|
+
// Connect to the given URL.
|
|
43
|
+
//
|
|
44
|
+
primus.on('outgoing::open', function opening() {
|
|
45
|
+
primus.emit('outgoing::end');
|
|
46
|
+
|
|
47
|
+
primus.socket = socket = factory(primus.merge(primus.transport,
|
|
48
|
+
primus.url,
|
|
49
|
+
primus.uri({ protocol: 'http:', query: true, object: true }), {
|
|
50
|
+
//
|
|
51
|
+
// Never remember upgrades as switching from a WIFI to a 3G connection
|
|
52
|
+
// could still get your connection blocked as 3G connections are usually
|
|
53
|
+
// behind a reverse proxy so ISP's can optimize mobile traffic by
|
|
54
|
+
// caching requests.
|
|
55
|
+
//
|
|
56
|
+
rememberUpgrade: false,
|
|
57
|
+
|
|
58
|
+
//
|
|
59
|
+
// Binary support in Engine.IO breaks a shit things. Turn it off for now.
|
|
60
|
+
//
|
|
61
|
+
forceBase64: true,
|
|
62
|
+
|
|
63
|
+
//
|
|
64
|
+
// Force timestamps on every single connection. Engine.IO only does this
|
|
65
|
+
// for polling by default, but WebSockets require an explicit `true`
|
|
66
|
+
// boolean.
|
|
67
|
+
//
|
|
68
|
+
timestampRequests: true,
|
|
69
|
+
path: this.pathname,
|
|
70
|
+
transports: !primus.AVOID_WEBSOCKETS
|
|
71
|
+
? ['polling', 'websocket']
|
|
72
|
+
: ['polling']
|
|
73
|
+
}));
|
|
74
|
+
|
|
75
|
+
//
|
|
76
|
+
// Setup the Event handlers.
|
|
77
|
+
//
|
|
78
|
+
socket.on('message', onmessage);
|
|
79
|
+
socket.on('error', onerror);
|
|
80
|
+
socket.on('close', onclose);
|
|
81
|
+
socket.on('open', onopen);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
//
|
|
85
|
+
// We need to write a new message to the socket.
|
|
86
|
+
//
|
|
87
|
+
primus.on('outgoing::data', function write(message) {
|
|
88
|
+
if (socket) socket.send(message);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
//
|
|
92
|
+
// Attempt to reconnect the socket.
|
|
93
|
+
//
|
|
94
|
+
primus.on('outgoing::reconnect', function reconnect() {
|
|
95
|
+
primus.emit('outgoing::open');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
//
|
|
99
|
+
// We need to close the socket.
|
|
100
|
+
//
|
|
101
|
+
primus.on('outgoing::end', function close() {
|
|
102
|
+
if (!socket) return;
|
|
103
|
+
|
|
104
|
+
socket.removeListener('message', onmessage);
|
|
105
|
+
socket.removeListener('error', onerror);
|
|
106
|
+
socket.removeListener('close', onclose);
|
|
107
|
+
socket.removeListener('open', onopen);
|
|
108
|
+
socket.close();
|
|
109
|
+
socket = null;
|
|
110
|
+
});
|
|
111
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
// Expose the module as new Transformer instance.
|
|
5
|
+
//
|
|
6
|
+
module.exports = require('../../transformer').extend({
|
|
7
|
+
// Creating a new real-time server.
|
|
8
|
+
server: require('./server'),
|
|
9
|
+
|
|
10
|
+
// The client-logic to connect with the a server.
|
|
11
|
+
client: require('./client'),
|
|
12
|
+
|
|
13
|
+
// The client-side library of engine.io.
|
|
14
|
+
library: require('fs').readFileSync(__dirname + '/library.js', 'utf-8')
|
|
15
|
+
});
|