创建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();
创建http.Server实例,端口占用就换个端口的更多相关文章
- windows查看端口占用 windows端口占用 查找端口占用程序 强制结束端口占用 查看某个端口被占用的解决方法 如何查看Windows下端口占用情况
windows下查询端口占用情况 ,强制结束端口占用程序 查询8080端口被那个程序占用 如何强制结束windows下端口占用情况? 下面操作在win10下 在控制台执行命令 1.列出所有端口的情 ...
- [转]Centos 查看端口占用情况和开启端口命令
http://www.cnblogs.com/xqzt/p/4919191.html 1.Centos 查看端口占用 比如查看 80 端口占用情况使用如下命令: lsof -i tcp:80 2.列出 ...
- cmd端口占用查看和关闭端口
cmd——回车,输入netstat -ano——回车,可以查看已占用的端口,记下端口的PID,然后打开任务管理器,点查看,选择列,勾选PID确定,找到对应的PID,结束进程,如果结束不了或者结束后还不 ...
- Centos6.9以下查看端口占用情况和开启端口命令
Centos查看端口占用情况命令,比如查看80端口占用情况使用如下命令: lsof -i tcp:80 列出所有端口 netstat -ntlp 1.开启端口(以80端口为例) ...
- Centos查看端口占用情况和开启端口命令
Centos查看端口占用情况命令,比如查看80端口占用情况使用如下命令: lsof -i tcp:80 列出所有端口 netstat -ntlp 1.开启端口(以80端口为例)方法一: /sbin/i ...
- Linux查看端口占用情况并释放端口占用
1.netstat -tunlp:查看所有tcp/udp端口占用及进程相关信息 2.netstat -tln | grep 端口号:查看特定端口占用情况 3.kill -9 进程ID(PID):释放指 ...
- 利用netstat和tasklist查看PC的端口占用情况 及80端口被占用
经常,我们在启动应用的时候发现系统需要的端口被别的程序占用,如何知道谁占有了我们需要的端口? 1.Windows平台在windows命令行窗口下执行: E:\oracle\ora92\bin>n ...
- 【Linux】lsof 命令,记一次端口占用查询
3月21日测试时,发现测试服务器启,总是报端口占用情况,察看端口占用情况 1-使用命令 netstat -tunlp |grep 端口号 差看下 这个端口被那个进程占用 我当前使用的 JBOSS 端口 ...
- linux(centos 7)下安装elasticsearch - head插件(端口占用,防火墙关闭)
本文章来自网络仅供个人学习记录之用 一:安装Git(如果未安装) 1, yum install git 2, git --version #查看版本 二:安装node(如果未安装) node安装 三: ...
随机推荐
- 拜小白教你OpenCV3.2.0+VS2017开发环境配置
第一部分:OpenCV3.2.0的下载 OpenCV官方下载地址: http://opencv.org/releases.html# 本人选择opencv3.2.0基于Windows平台.读者根据自己 ...
- blfs(systemd版本)学习笔记-配置远程访问和管理lfs系统
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 要实现远程管理和配置lfs系统需要配置以下软件包: 前几页章节脚本的配置:https://www.cnblogs.com/ren ...
- Python 多线程、多进程 (三)之 线程进程对比、多进程
Python 多线程.多进程 (一)之 源码执行流程.GIL Python 多线程.多进程 (二)之 多线程.同步.通信 Python 多线程.多进程 (三)之 线程进程对比.多线程 一.多线程与多进 ...
- csharp:FTP Client Library using FtpWebRequest or Sockets
https://netftp.codeplex.com/SourceControl/latest http://ftplib.codeplex.com/ https://www.codeproject ...
- 【读书笔记】iOS-分类与协议
分类与协议是Object-C特有概念,分类(Category)可以认为是一种继承性的扩展,而协议(Protocol)可以理解为Java中的Interface(接口)或者C++的纯虚类. 参考资料:&l ...
- mysql 中表和数据库名称不要使用 '-' 命名
mysql 中表和数据库名称不要使用 '-' 命名 若使用这个符号,比如 my-name 做为数据库表名称 那么在 sql 中必须如下: select * from `my-name`
- 西安OpenParty11月29日活动高清图文回顾——新增西安APEC蓝美图!
本次活动由西安OpenParty负责线下活动组织运营,线上由InfoQ-QClub.OSChina协办. OSChina活动召集帖:运维为王——应用系统.DevOps与Docker(11月29日) I ...
- 听说你还不会用Dagger2?Dagger2 For Android最佳实践教程
前言 Dagger2是现在非常火的一个依赖注入框架,目前由Google维护,在Github上面已经有12K star了.Dagger2的入门门槛其实是比较高的,据了解,目前有很多Android工程师对 ...
- 监听软件异常崩溃并且保持日志--CrashHandler编写自己的异常捕获类
平时写代码,我们可能会抛出各种异常,这些异常有些是我们测试过程中发现进行解决的,但是也有一些异常是我们未知的,不论是代码的逻辑问题还是Android本身底层的一些bug,我们都需要及时了解并进行解决. ...
- SpringMVC处理请求
HttpServletBean HttpServletBean主要参与了创建工作,并没有涉及请求的处理. FrameworkServlet FrameworkServlet的service方法里添加了 ...