/**
* 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();

创建http.Server实例,端口占用就换个端口的更多相关文章

  1. windows查看端口占用 windows端口占用 查找端口占用程序 强制结束端口占用 查看某个端口被占用的解决方法 如何查看Windows下端口占用情况

    windows下查询端口占用情况 ,强制结束端口占用程序 查询8080端口被那个程序占用 如何强制结束windows下端口占用情况? 下面操作在win10下 在控制台执行命令   1.列出所有端口的情 ...

  2. [转]Centos 查看端口占用情况和开启端口命令

    http://www.cnblogs.com/xqzt/p/4919191.html 1.Centos 查看端口占用 比如查看 80 端口占用情况使用如下命令: lsof -i tcp:80 2.列出 ...

  3. cmd端口占用查看和关闭端口

    cmd——回车,输入netstat -ano——回车,可以查看已占用的端口,记下端口的PID,然后打开任务管理器,点查看,选择列,勾选PID确定,找到对应的PID,结束进程,如果结束不了或者结束后还不 ...

  4. Centos6.9以下查看端口占用情况和开启端口命令

    Centos查看端口占用情况命令,比如查看80端口占用情况使用如下命令:   lsof -i tcp:80   列出所有端口   netstat -ntlp   1.开启端口(以80端口为例)     ...

  5. Centos查看端口占用情况和开启端口命令

    Centos查看端口占用情况命令,比如查看80端口占用情况使用如下命令: lsof -i tcp:80 列出所有端口 netstat -ntlp 1.开启端口(以80端口为例)方法一: /sbin/i ...

  6. Linux查看端口占用情况并释放端口占用

    1.netstat -tunlp:查看所有tcp/udp端口占用及进程相关信息 2.netstat -tln | grep 端口号:查看特定端口占用情况 3.kill -9 进程ID(PID):释放指 ...

  7. 利用netstat和tasklist查看PC的端口占用情况 及80端口被占用

    经常,我们在启动应用的时候发现系统需要的端口被别的程序占用,如何知道谁占有了我们需要的端口? 1.Windows平台在windows命令行窗口下执行: E:\oracle\ora92\bin>n ...

  8. 【Linux】lsof 命令,记一次端口占用查询

    3月21日测试时,发现测试服务器启,总是报端口占用情况,察看端口占用情况 1-使用命令 netstat -tunlp |grep 端口号 差看下 这个端口被那个进程占用 我当前使用的 JBOSS 端口 ...

  9. linux(centos 7)下安装elasticsearch - head插件(端口占用,防火墙关闭)

    本文章来自网络仅供个人学习记录之用 一:安装Git(如果未安装) 1, yum install git 2, git --version #查看版本 二:安装node(如果未安装) node安装 三: ...

随机推荐

  1. Tomcat性能调优 通过ExpiresFilter设置资源缓存

    转自 http://www.cnblogs.com/daxin/p/3995287.html [简介] ExpiresFilter是Java servlet API 当中的一部分,它负责控制设置res ...

  2. JS如何判断一个对象是否为空、是否有某个属性

    一.js判断一个对象是否为空 方法一: let obj1 = {} let obj2 = {a:1} function empty(obj){ for (let key in obj){ return ...

  3. Python 简单分页思路

    一: li = [] for i in range(1000): li.append(i) while True: p = input('input page: ') p = int(p) start ...

  4. 【代码笔记】Web-利用Dreamweaver实现form

    一,打开Dreamweaver---->File---New---->如下图所示.选择HTML,点击OK. 二,会出现如下图所示界面.把光标放到Body处. 三,将上面的栏切换到Desig ...

  5. Android学习笔记----天地图API开发之UnsatisfiedLinkError

    由于在jniLibs目录下移除了x86的相关so文件,后来又因为需要在PC模拟器上调试,将该文件夹恢复后,增加了天地图的sdk,却忘记将libMapEngine.so文件同时拷贝至x86目录下,导致如 ...

  6. 【Java入门提高篇】Day32 Java容器类详解(十四)ArrayDeque详解

    今天来介绍一个不太常见也不太常用的类——ArrayDeque,这是一个很不错的容器类,如果对它还不了解的话,那么就好好看看这篇文章吧. 看完本篇,你将会了解到: 1.ArrayDeque是什么? 2. ...

  7. Python 文档学习

    1.在命令行执行Python脚本(获取输入) import sys print(sys.argv[1]) 2.compile Python(编译Python) 编译后,生成的文件是.pyc,但是要知道 ...

  8. 洗礼灵魂,修炼python(45)--巩固篇—【转载】类的__now__和__init__

    学到这里了,相信你应该对__init__非常熟悉了,就是构造器呗,当类被实例化时初始化的作用 但__init__其实不是实例化一个类的时候第一个自动调用的方法.当实例化一个类时,最先被调用的方法 其实 ...

  9. SQL Server 全文索引介绍(转载)

    概述 全文引擎使用全文索引中的信息来编译可快速搜索表中的特定词或词组的全文查询.全文索引将有关重要的词及其位置的信息存储在数据库表的一列或多列中.全文索引是一种特殊类型的基于标记的功能性索引,它是由 ...

  10. Jmeter参数化方法

    用Jmeter测试时包含两种情况的参数:一种是在url中,一种是请求中需要发送的参数. 设置参数值的方法有如下几种: 一.函数助手 用Jmeter中的函数获取参数值,__Random,__thread ...