6

http.Serverデフォルトモジュールのオブジェクトを使用していhttpます(-> API)。

クライアントが接続すると、requestイベントはサーバーによって送信され、http.ServerRequestオブジェクトがイベントハンドラーに渡されます。そのリクエストオブジェクトは、次の3つのイベントを発行します。

  • データ(受信データ)
  • 終了(リクエスト終了)
  • close(接続が閉じています)

クライアントの初期(TCP)接続を維持し、それをいくつかの要求に再利用したいと思います。クライアントは、「Connection:keep-alive」ヘッダーを送信するため、この動作をサポートします。

しかし、node.jsを使用してこれをどのように実現しますか?私の問題は、最初のリクエストの後に終了イベントが発行され、公式APIがそのイベントについて述べているように:

リクエストごとに1回だけ発行されます。その後、リクエストで「データ」イベントは発行されなくなります。

はい、そのリクエストは使用できません。しかし、同じTCP接続で作業し、その接続で新しい要求を作成する方法はありますか?

背景:私はプロキシの実装に取り​​組んでいます。ユーザーがNTLMを使用するWebサイトにアクセスする場合、このタイプの認証でこの問題が発生しないようにするために必要な少なくとも3つのクライアント要求に対して、1つの接続に固執する必要があります。

私が何をしようとしているのか分かりますか?

前もって感謝します!

4

1 に答える 1

0

ノードv6.17でこのコードを実行すると、キープアライブが機能していないことが示唆されます

function notifyNotKeptAlive(httpObject, eventName, httpObjectName){
    httpObject.on(eventName, function(socket){
        socket.on('close', function(){
                console.log("Yeeouch !  "+httpObjectName+" connection was not kept alive!");
        });
    });
}
var http=require('http');
var count=1;
var srv = http.createServer(function (req, res) {
    var secs;
    if ( (count%2)==1){secs=3;}
    else {secs=1;}
    console.log("Got http request #"+count+" so server waits "+secs+" seconds to respond");
    var countForThisClosure=count;
    setTimeout(function(){
        console.log("Waking up from sleep of "+secs);
        res.writeHead(200, {'Content-Type': 'text/plain'});
        if (secs===3){
            res.end('Visit #'+countForThisClosure+' costing a wait of '+secs+' seconds !!');
        } else {
            res.end('Visit #'+countForThisClosure+' costing a wait of '+secs+' seconds !!');
        }
    }, secs*1000);
    count++;
}).listen(8090);

notifyNotKeptAlive(srv, 'connection', 'http server');

for (var i=0;i<2;i++){
    var req=http.request( {'host': 'localhost', 'port':8090}, function (res) {
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            console.log('INCOMING <---' + chunk);
        });
        }
    );
    notifyNotKeptAlive(req, 'socket', 'http client');
    req.end();
}

IT は、Epeli が提供してくれた http lib ソースの 1263 行目に感嘆符を追加したときにのみ機能しました。したがって、"if (req.shouldKeepAlive){" と書かれている以下の行は、代わりに "if (! req.shouldKeepAlive){" res.on('end', function() {

if (req.shouldKeepAlive) {
      socket.removeListener('close', closeListener);
      socket.removeListener('error', errorListener);
      socket.emit('free');
    }
  });

この行は、1113 行目から始まる ClientRequest.prototype.onSocket クロージャー内に設定された on'end' コールバック内にあります。

この http lib ソースへのリンクは (Epeli のものと同じ) https://github.com/joyent/node/blob/e8067cb68563e3f3ab760e3ce8d0aeb873198f36/lib/http.js#L889です。

于 2012-05-15T17:30:39.847 に答える