2013-07-30 20 views

回答

7

如果您不想进行环回连接,那么最简单的解决方案是用假请求手动调用您的服务器。

您将不得不重新实现IncomingMessage。您还应该使用Async#map等待处理所有请求。

这里的基本思想是:

 
// You'll probably have more work to do to reimplement http basic API. 
function FakeRequest(request) { 
    this.url = '/' + request.relative_url; 
    this.method = request.method; 
    this.headers = request.headers; 
} 

function FakeResponse() { 
    Stream.call(this); 

    this.statusCode = null; 
    this.body = ''; 
} 

FakeResponse.prototype.write = function (chunk) { 
    this.body += chunk.toString('utf8'); 

    return true; 
}; 

util.inherits(FakeResponse, Stream); 

app.post('/', function (req, res) { 
    var requests = JSON.parse(req.body.batch); 

    async.map(requests, function (request, done) { 
    var fakeReq = new FakeRequest(request), 
     fakeRes = new FakeResponse(); 

    // call Express' middleware manually 
    app(fakeReq, fakeRes); 

    // this will trigger when the response is ready. 
    fakeRes.once('end', function() { 
     // don't leak listeners 
     fakeRes.removeAllListeners(); 
     done(null, fakeRes); 
    }); 

    fakeRes.once('error', function (err) { 
     fakeRes.removeAllListeners(); 
     done(err); 
    }); 
    }, function (err, responses) { 
    if (err) 
     return res.send(err); 

    res.send(responses); 
    }); 
}); 

http.createServer(app).listen(app.get('port'), function(){ 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

UPDATE

实际上,我不知道你回送的意思,但你有两个选择:

  • 打开的批处理中每个请求的HTTP连接,这比较容易实现但速度较慢。

  • 我上面概述的解决方案:直接调用Express中间件而不打开HTTP请求。

我的印象是,你不想第一个解决方案。但是,这就是我会先尝试的,即使速度较慢:

  • 当您缩放时,更容易将批连接分散到多个实例中。
  • 您不会绕过您可能具有的任何负载限制机制(这会阻止单个Express实例同时处理太多的请求)。

但是一定要禁用HTTP Agent

+0

谢谢!在尝试之前,我还有其他问题。你认为回送连接方式在性能上比传统的http请求方式更好吗?对我来说是的。我想知道你的答案。如果他们没有区别,我只会使用传统的Async#map – WooD

+0

我会更新我的答案,这里没有足够的空间。 –

+0

我尝试使用Express框架的这种方法,但发现它失败,“res.status不是一个函数” – swateek