2016-09-24 5 views
1

中間で明示的にhttp応答を中止するにはどうすればよいですか? 私の場合、外部ソースから生成されたデータを提供しています。サービスを開始する前に、サイズ(コンテンツ長)を知っています。しかし、外部ソースが私に完全な内容を与える前に私にデータを送るのを止めれば、私はその要求を中止して、受信側でエラーイベントが引き起こされるようにしたい。nodejs:進行中にhttp応答を中止します

ここで簡単なコードは、サーバーの:

//server 
var express = require('express'); 
var app = express(); 
app.use(function(req, res, next){ 
    res.setHeader('Content-Length', 100); 
    res.writeHead(200); 
    res.write('1234567890'); 
    setTimeout(function() { res.connection.destroy(); }, 500); 
}); 
app.listen(8080); 

//client 
var http = require('http'); 
http.get('http://localhost:8080/', function(res){ 
    var length = 0; 
    console.log('expected size: ', res.headers['content-length']); 
    res.on('data', function(chunk){ length += chunk.length; }); 
    res.on('end', function(){ console.log('received: ', length); }); 
}).on('error', function(e){ 
    console.log('error', e); 
}); 

すべてがOKだったとして、クライアントの振る舞い接続がリセットされたというエラーを表示してはならないことが予想されますだけでも10バイトのうちかかわらず100を受け取った。

要求が実行できないことがわかっている場合、送信側で接続を中止する方法はありますか?私が見つけた1つの方法は、そのタイマー内で例外をスローすることです、その後受信者はエラーをログに記録しますが、私は例外をスローしたくありません。

+0

Hmm。私はあなたがノードサーバーからそれを返す前に、外部ソースから完全なデータを取得する必要があると思います。 –

+0

@RobertMoskalオプションではない、私はTCP接続を中止するために熱心に知っておく必要があります。私はそのような方法がないとは信じられません。私は実際には中止する必要があり、回避策や他の解決策はありません。 – Pavel

答えて

1

HTTP応答を終了するには、res.end()とするのが理想的です。チャンクされた転送エンコーディングまたはHTTPキープアライブなしの接続の場合、これは正常に応答を終了します。

ほとんどのHTTP接続ではHTTPキープアライブがサポートされますが、Content-Lengthヘッダーがあるため、転送エンコーディングはチャンクされません。あなたの場合、下にあるソケットを閉じる必要があります。 req.connectionプロパティを確認し、.end()を呼び出してください。これは文書化されていませんが、何年も前からありましたが、現在は安全です。接続を確立するためのさらに適切な方法にはlistening for it on the server objectが含まれますが、要求との接続を関連付けるのは難しいです。

ほとんどのHTTPクライアントでは、これは最高の警告であり、通常はエラーではないことに注意してください。クライアントコードを管理している場合は、受信したデータの長さと予想された長さを比較することで、この状態を検出できます。

+0

私のコードをチェックしましたか?私はreq.connection.destroy()を行います。明らかに私はres.end()について知っています。 res.end()を実行することはできません。絶対に接続を閉じる必要があります。あなたはそれを認識していますか? – Pavel

+0

はい、コードを確認しました。あなたのソケットで '.end()'を使う... '.destroy()'はあなたが望むものではありません。そして、キープアライブがない状態で 'res.end()'はどう思いますか?接続を閉じます。私はそれがあなたの場合に関連するかもしれないので、それを言います。私の答え、私が提案した2つの選択肢をもう一度読んで、あなたに当てはまるものを選んでください。 – Brad

+0

厳密には、res.end()は、非チャンク送信が使用されている場合にキープアライブの場合に大惨事を引き起こします。 socket.endを試してみましょう、まだ試してみませんでした。 – Pavel

関連する問題