节点js套接字解释

时间:2016-01-15 00:48:43

标签: javascript node.js asynchronous

我正在构建一个应用程序,它将对远程api服务器进行大约一百万次调用。我是否可以限制连接数量,例如10?我将max套接字设置为10会这样做吗?

我试图了解这些参数的作用:

keepAlive: false,
maxSockets: 999,
maxFreeSockets: 1

在节点http get函数中,在以下代码中:

var inputData = [];

for(i=1; i<=5000;i++){
    inputData.push('number' + i);
}

var options = {
    host: "localhost",
    port: 80,
    path: "/text.txt",
    keepAlive: false,
    maxSockets: 999,
    maxFreeSockets: 1
}


var limit = inputData.length;
var counter = 0;

function fetchData(number){

    return new Promise(function(resolve, reject){
        var http = require('http');

        fetch  = function(resp){
            var body = '';
            resp.on('data',function(chunk){
                body += chunk;
            })
            resp.on('end',function(){
                console.log(resp)
                resolve()
            })
            resp.on('error',function(err){
                console.log('error');
            })
        }
        var req = http.request(options, fetch);

        req.end();

    })
}



Promise.all(inputData.map(number => fetchData(number))).then(function(results) {
    console.log('finished');
    connection.end();

})
.catch(function(error) {
    console.log('there wa an error');
    console.log(error);
});

2 个答案:

答案 0 :(得分:6)

你真的不想发起1,000,000个请求,并且不知何故希望maxSockets一次管理100个请求。有很多原因导致这不是一个很好的做事方式。相反,您应该使用自己的代码来管理一次100个实时连接的数量。

有很多方法可以做到这一点:

  1. 编写自己的代码,激活100,然后每次完成,它会激活下一个代码。

  2. 使用Bluebird的Promise.map(),它具有内置的并发功能,可以同时管理有多少是飞行时间。

  3. 使用Async的async.mapLimit(),它具有内置的并发功能,可以同时管理有多少是空中飞行。

  4. 至于自己编写代码来执行此操作,您可以执行以下操作;

    function fetchAll() {
        var start = 1;
        var end = 1000000;
        var concurrentMax = 100;
        var concurrentCnt = 0;
        var cntr = start;
        return new Promise(function(resolve, reject) {
    
            // start up requests until the max concurrent requests are going
            function run() {
                while (cntr < end && concurrentCnt < concurrentMax) {
                    ++concurrentCnt;
                    fetchData(cntr++).then(function() {
                        --concurrentCnt;
                        run();
                    }, function(err) {
                        --concurrentCnt;
                        // decide what to do with error here
                        // to continue processing more requests, call run() here
                        // to stop processing more requests, call reject(err) here
                    });
                }
                if (cntr >= end && concurrentCnt === 0) {
                    // all requests are done here
                    resolve();
                }        
            }
    
            run();
        });
    
    }
    

答案 1 :(得分:1)

我决定使用异步库。

以下是我对此的完整解决方案:

var async = require('async')

var http = require('http');

var inputData = [];

for(i=1; i<=2000;i++){
    inputData.push('number' + i);
}

var options = {
    host: "o2.pl",
    path: "/static/desktop.css?v=0.0.417",
    port: 80
}

function fetchData(number, callback){

    return new Promise(function(resolve, reject){

        fetch  = function(resp){
            var body = '';
            resp.on('data',function(chunk){
                body += chunk;
            })
            process.stdout.write('.')

            callback()

            resp.on('error',function(err){
                console.log('error');
                console.log(err);

            })
        }
        var req = http.request(options, fetch);

        req.end();

    })
}

function foo(item, callback){

    return callback(false, 'foo');
}

async.mapLimit(inputData,100,fetchData,function(err, result){
    console.log('finished');
})

感谢您的帮助。