/**
* 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. 微信服务号获取openid方法

    public function tetst(){ if(!isset($_GET['code'])){ $APPID = $this->app_id; $ran = rand(1,100); / ...

  2. 【代码笔记】Web-HTML-布局

    一, 效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  3. 微软Azure AspNetCore微服务实战 第一期

    微服务大家已经不在陌生了,相对传统单体架构其带来了更大的灵活性与多方位的效率提升. 2017官方发布了EshopOnContainers的微服务项目,其结合了.Net Core.Azure.Docke ...

  4. mysql的varchar字段可以存储多少个中文字符

    创建数据库,并创建一张表mytb进行测试 ******************************************************************************* ...

  5. 从零自学Java-10.充分利用现有对象

    1.超类和子类的设计:2.建立继承层次:3.覆盖方法. 程序StringLister:使用数组列表和特殊的for循环将一系列字符串按字母顺序显示到屏幕上.这些字符串来自一个数组和命令行参数 packa ...

  6. 使用wxpy自动发送微信消息(加强版)

    通过使用wxpy自动发送微信消息后,笔者又加强了发送消息,堪称消息爆炸式发送 目前设置的为10秒发送一次,发送9次,每次发送10条内容 import requests import wxpy from ...

  7. python第七十九天--第十四周作业

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. js中var的有或无--重复声明和以后的声明

    js中var的有或无--重复声明和以后的声明 使用var语句多次声明一个变量不仅是合法的,而且也不会造成任何错误. 如果重复使用的一个声明有一个初始值,那么它担当的不过是一个赋值语句的角色. 如果重复 ...

  9. orcale 使用创建日期排序然后分页每次取排序后的固定条数

    需求: 一个使用mybatis分页插件的分页列表, 现在要求新增一条数据或者修改一条数据后,显示在最前端 思路: 使用sql , 先将查询出来的数据排序, 然后使用rownum > page*s ...

  10. css设置文字不能选中状态

    高版本浏览器的处理方式 -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-u ...