Skip to content

Commit 2abb217

Browse files
efkandarrachequesne
authored andcommitted
[feat] Make generateId method async (#535)
That change will allow to retrieve the client id asynchronously, from a database for example.
1 parent 3ee803a commit 2abb217

File tree

3 files changed

+60
-43
lines changed

3 files changed

+60
-43
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ to a single process.
261261
- Overwrite this method to generate your custom socket id.
262262
- **Parameters**
263263
- `http.IncomingMessage`: a node request object
264-
- **Returns** A socket id for connected client.
264+
- `Function`: a callback method which contains an error (if there is) object and the generated id value
265265

266266
<hr><br>
267267

lib/server.js

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,8 @@ function sendErrorMessage (req, res, code) {
281281
* @api public
282282
*/
283283

284-
Server.prototype.generateId = function (req) {
285-
return base64id.generateId();
284+
Server.prototype.generateId = function (req, callback) {
285+
callback(null, base64id.generateId());
286286
};
287287

288288
/**
@@ -294,52 +294,56 @@ Server.prototype.generateId = function (req) {
294294
*/
295295

296296
Server.prototype.handshake = function (transportName, req) {
297-
var id = this.generateId(req);
298-
299-
debug('handshaking client "%s"', id);
300-
301-
try {
302-
var transport = new transports[transportName](req);
303-
if ('polling' === transportName) {
304-
transport.maxHttpBufferSize = this.maxHttpBufferSize;
305-
transport.httpCompression = this.httpCompression;
306-
} else if ('websocket' === transportName) {
307-
transport.perMessageDeflate = this.perMessageDeflate;
297+
var self = this;
298+
this.generateId(req, function (err, id) {
299+
if (err) {
300+
sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST);
301+
return;
308302
}
303+
debug('handshaking client "%s"', id);
304+
305+
try {
306+
var transport = new transports[transportName](req);
307+
if ('polling' === transportName) {
308+
transport.maxHttpBufferSize = self.maxHttpBufferSize;
309+
transport.httpCompression = self.httpCompression;
310+
} else if ('websocket' === transportName) {
311+
transport.perMessageDeflate = self.perMessageDeflate;
312+
}
309313

310-
if (req._query && req._query.b64) {
311-
transport.supportsBinary = false;
312-
} else {
313-
transport.supportsBinary = true;
314+
if (req._query && req._query.b64) {
315+
transport.supportsBinary = false;
316+
} else {
317+
transport.supportsBinary = true;
318+
}
319+
} catch (e) {
320+
sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST);
321+
return;
322+
}
323+
var socket = new Socket(id, self, transport, req);
324+
325+
if (false !== self.cookie) {
326+
transport.on('headers', function (headers) {
327+
headers['Set-Cookie'] = cookieMod.serialize(self.cookie, id,
328+
{
329+
path: self.cookiePath,
330+
httpOnly: self.cookiePath ? self.cookieHttpOnly : false
331+
});
332+
});
314333
}
315-
} catch (e) {
316-
sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST);
317-
return;
318-
}
319-
var socket = new Socket(id, this, transport, req);
320-
var self = this;
321334

322-
if (false !== this.cookie) {
323-
transport.on('headers', function (headers) {
324-
headers['Set-Cookie'] = cookieMod.serialize(self.cookie, id,
325-
{
326-
path: self.cookiePath,
327-
httpOnly: self.cookiePath ? self.cookieHttpOnly : false
328-
});
329-
});
330-
}
335+
transport.onRequest(req);
331336

332-
transport.onRequest(req);
337+
self.clients[id] = socket;
338+
self.clientsCount++;
333339

334-
this.clients[id] = socket;
335-
this.clientsCount++;
340+
socket.once('close', function () {
341+
delete self.clients[id];
342+
self.clientsCount--;
343+
});
336344

337-
socket.once('close', function () {
338-
delete self.clients[id];
339-
self.clientsCount--;
345+
self.emit('connection', socket);
340346
});
341-
342-
this.emit('connection', socket);
343347
};
344348

345349
/**

test/server.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
'use strict';
12
/* eslint-disable standard/no-callback-literal */
23

34
/**
@@ -234,8 +235,8 @@ describe('server', function () {
234235

235236
var customId = 'CustomId' + Date.now();
236237

237-
engine.generateId = function (req) {
238-
return customId;
238+
engine.generateId = function (req, callback) {
239+
callback(null, customId);
239240
};
240241

241242
var socket = new eioc.Socket('ws://localhost:%d'.s(port));
@@ -249,6 +250,18 @@ describe('server', function () {
249250
});
250251
});
251252

253+
it('should disallow connection when custom id cannot be generated', function (done) {
254+
let engine = listen({ allowUpgrades: false }, port => {
255+
engine.generateId = (req, callback) => {
256+
callback(new Error('no ID found'));
257+
};
258+
259+
let socket = new eioc.Socket('ws://localhost:%d'.s(port));
260+
socket.on('open', () => done(new Error('should not be able to connect')));
261+
socket.on('error', () => done());
262+
});
263+
});
264+
252265
it('should exchange handshake data', function (done) {
253266
listen({ allowUpgrades: false }, function (port) {
254267
var socket = new eioc.Socket('ws://localhost:%d'.s(port));

0 commit comments

Comments
 (0)