创建http.Server实例,端口占用就换个端口
/** * Created by Sorrow.X on 2017/10/25. */ const http = require('http'); const url = require('url'); const net = require('net'); // 单例 let httpServer = (function() { let port = 8888; let server = null; let serverStartedCb = null; let noop = function() {}; // 初始化http服务器 let initServer = function({serverStarted}) { serverStartedCb = serverStarted || noop; startServer(increPort()); }; // 关闭服务器 let closeServer = function() { if (server) { server.close(); server = null; }; }; // 端口增加 function increPort() { return ++port; }; // 格式化url function format(str) { let obj = {}; str = str.substr(str.indexOf('?') + 1); let arr = str.split('&'); arr.forEach(function(item) { let a = item.split('='); obj[a[0]] = a[1]; }); return obj; }; // 启动服务器 function _server(port) { server = new http.Server(); server.on('request',(req, res)=>{ let content = { Code: -1, Body: { message: 'request url error' } }; if (req.url.indexOf('ball/queryUrl') > 0) { let obj = format(req.url); if (obj.type == '1') { content.Code = 0; content.Body = { message: 'hi' }; }; }; //设置应答头信息 res.writeHead(200,{'Content-Type':'text/plain'}); res.write(JSON.stringify(content)); res.end(); }); server.on('listening', () => { console.log("server listening, 端口号和url为: ", `localhost:${port}`); serverStartedCb(null); }); server.on('connection', () => { console.log("server connection..."); }); server.on('close', () => { console.log('server close...'); }); server.on('error', (err) => { server.close(); server = null; serverStartedCb(new Error(err)); console.log('server error: ', err); }); server.listen(port); }; // 检测port是否被占用 function probe(port, callback) { let server = net.createServer().listen(port); let calledOnce = false; let timeoutRef = setTimeout(function () { calledOnce = true; callback(false, port); }, 2000) timeoutRef.unref(); // 取消定时器 let connected = false; server.on('listening', function() { clearTimeout(timeoutRef); if (server) server.close(); if (!calledOnce) { calledOnce = true; callback(true, port); // true 表示未被占用 }; }); server.on('error', function(err) { clearTimeout(timeoutRef); let result = true; if (err.code === 'EADDRINUSE') result = false; // 占用 if (!calledOnce) { calledOnce = true; callback(result, port); // false 表示占用 }; }); }; function startServer(port){ probe(port, function(bool, port) { // 端口被占用: bool 返回false; port:传入的端口号 if (bool === true) { // 端口号未被占用 _server(port); } else { // 已占用 closeServer(); _server(increPort()); }; }); }; let single; return function() { return single ? single : (single = {initServer, closeServer}); }; }()); // module.exports = httpServer(); // test var ballServer = httpServer(); var ballServer2 = httpServer(); console.log(ballServer === ballServer2); // 测试是否同一个对象 ballServer.initServer({ serverStarted: function(err) { if (!err) { console.log('服务已启动: '); }; } }); // ballServer.closeServer();
开心的做一个无忧无虑的码农,争取每天进步一点。