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 | ||
|  |   } | ||
|  | }; |