2013-07-30 22 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