forked from coolaj86/goldilocks.js
108 lines
2.3 KiB
JavaScript
108 lines
2.3 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
var serversMap = module.exports._serversMap = {};
|
||
|
|
||
|
module.exports.addTcpListener = function (port, handler) {
|
||
|
var PromiseA = require('bluebird');
|
||
|
|
||
|
return new PromiseA(function (resolve, reject) {
|
||
|
var stat = serversMap[port] || serversMap[port];
|
||
|
|
||
|
if (stat) {
|
||
|
if (stat._closing) {
|
||
|
module.exports.destroyTcpListener(port);
|
||
|
}
|
||
|
else if (handler !== stat.handler) {
|
||
|
|
||
|
// we'll replace the current listener
|
||
|
stat.handler = handler;
|
||
|
resolve();
|
||
|
return;
|
||
|
}
|
||
|
else {
|
||
|
// this exact listener is already open
|
||
|
resolve();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var enableDestroy = require('server-destroy');
|
||
|
var net = require('net');
|
||
|
var resolved;
|
||
|
var server = net.createServer();
|
||
|
|
||
|
stat = serversMap[port] = {
|
||
|
server: server
|
||
|
, handler: handler
|
||
|
, _closing: false
|
||
|
};
|
||
|
|
||
|
server.on('connection', function (conn) {
|
||
|
conn.__port = port;
|
||
|
conn.__proto = 'tcp';
|
||
|
stat.handler(conn);
|
||
|
});
|
||
|
server.on('error', function (e) {
|
||
|
delete serversMap[port];
|
||
|
|
||
|
if (!resolved) {
|
||
|
reject(e);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (handler.onError) {
|
||
|
handler.onError(e);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
throw e;
|
||
|
});
|
||
|
|
||
|
server.listen(port, function () {
|
||
|
resolved = true;
|
||
|
resolve();
|
||
|
});
|
||
|
|
||
|
enableDestroy(server); // adds .destroy
|
||
|
});
|
||
|
};
|
||
|
module.exports.closeTcpListener = function (port) {
|
||
|
var PromiseA = require('bluebird');
|
||
|
|
||
|
return new PromiseA(function (resolve) {
|
||
|
var stat = serversMap[port];
|
||
|
if (!stat) {
|
||
|
return;
|
||
|
}
|
||
|
stat.server.on('close', function () {
|
||
|
// once the clients close too
|
||
|
delete serversMap[port];
|
||
|
if (stat._closing) {
|
||
|
stat._closing(); // resolve
|
||
|
stat._closing = null;
|
||
|
}
|
||
|
stat = null;
|
||
|
});
|
||
|
stat._closing = resolve;
|
||
|
stat.server.close();
|
||
|
});
|
||
|
};
|
||
|
module.exports.destroyTcpListener = function (port) {
|
||
|
var stat = serversMap[port];
|
||
|
delete serversMap[port];
|
||
|
stat.server.destroy();
|
||
|
if (stat._closing) {
|
||
|
stat._closing();
|
||
|
stat._closing = null;
|
||
|
}
|
||
|
stat = null;
|
||
|
};
|
||
|
|
||
|
module.exports.listeners = {
|
||
|
tcp: {
|
||
|
add: module.exports.addTcpListener
|
||
|
, close: module.exports.closeTcpListener
|
||
|
, destroy: module.exports.destroyTcpListener
|
||
|
}
|
||
|
};
|