zoukankan      html  css  js  c++  java
  • 创建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();
  • 相关阅读:
    设计模式--单例模式(Singleton)
    C# 和.Net 特性
    Fiddler 教程
    史铁生遗作:昼信基督夜信佛
    如何实现早日退休理想
    Linux 常用
    Golang 读书
    Python 读书
    RbMQ 简介
    UML 简介
  • 原文地址:https://www.cnblogs.com/sorrowx/p/7730094.html
Copyright © 2011-2022 走看看