/**
* 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. Linux环境变量详解与应用

    在bash shell中,环境变量分为: >全局变量 >局部变量 全局变量,不仅对shell可见,对其子进程也可见 查看预设的全局环境变量: ghostwu@dev:~$ printenv ...

  2. blfs(systemv版本)学习笔记-编译安装openssh软件包

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! openssh项目地址:http://www.linuxfromscratch.org/blfs/view/8.3/postlf ...

  3. Fragment问题集

    最近做一个APP  ,因为在慕课网上学习到了新的方法来做Tab(APP主界面)效果,所以刚学不久久用起来了 用的Fragment实现Tab方法 查询了一下午的安卓资料,关于这个东西是在安卓3.0以后的 ...

  4. 简单的TabLayout+Fragment选项卡

    TabLayout属性: app:tabIndicatorColor="#fff"  //下方滚动的下划线颜色 app:tabIndicatorHeight="10dp& ...

  5. Retrofit 代理模式

    https://blog.csdn.net/H176Nhx7/article/details/78139406

  6. springboot 学习之路 20 (整合RabbitMQ)

    整合RabbitMQ: 我的操作系统是window7 ,所以在整合ribbotMQ之前需要先安装rabbitMq服务:安装步骤请参考:window下安装RabbitMQ  这个详细介绍了安装步骤,请按 ...

  7. 导入另一个 Git库到现有的Git库并保留提交记录

    在要合并到的目标git仓库,执行 "git pull  远程分支地址/本地git仓库根目录"

  8. Django的认证系统—auth模块

    Django的认证系统 auth模块的知识点总结: 1. 创建超级用户 python manage.py createsuperuser from django.contrib import auth ...

  9. 《R数据挖掘入门》彩色插图(第9章)

    图9.5  图9.9

  10. Lucene创建索引流程

    1.创建索引流程 原始文档:互联网上的网页(爬虫或蜘蛛).数据库中的数据.磁盘上的文件 创建文档对象(非结构化数据) 文档对象中的属性不叫属性现在成为域. 每个 Document 可以有多个 Fiel ...