10msごとにクライアントにデータを繰り返し送信する次のコードがある場合:
setInterval(function() {
res.write(somedata);
}, 10ms);
クライアントがデータを受信するのが非常に遅い場合はどうなりますか?
サーバーでメモリ不足エラーが発生しますか?
編集:実際には接続は維持され、サーバーはjpegデータを際限なく送信します(HTTPマルチパート/ x-mixed-replaceヘッダー+ボディ+ヘッダー+ボディ.....)
node.jsのresponse.writeは非同期で
あるため、一部のユーザーは推測しますデータを内部バッファーに保存し、低レイヤーが送信できることを通知するまで待機する可能性がある
ため、内部バッファーが大きくなります。
私が正しければ、これを解決するにはどうすればよいですか?
問題は、単一の書き込み呼び出しでデータが送信されたときに node.js が通知しないことです。
言い換えれば、この方法は理論的には「メモリ不足」のリスクがなく、それを修正する方法をユーザーに伝えることはできません。
更新:
user568109 によって与えられたキーワード「drain」イベントによって、node.js のソースを調査し、結論を得ました:
それは本当に「メモリ不足」エラーを引き起こします。response.write(...)===false の戻り値を確認してから、応答の「ドレイン」イベントを処理する必要があります。
http.js:
OutgoingMessage.prototype._buffer = function(data, encoding) {
this.output.push(data); //-------------No check here, will cause "out-of-memory"
this.outputEncodings.push(encoding);
return false;
};
OutgoingMessage.prototype._writeRaw = function(data, encoding) { //this will be called by resonse.write
if (data.length === 0) {
return true;
}
if (this.connection &&
this.connection._httpMessage === this &&
this.connection.writable &&
!this.connection.destroyed) {
// There might be pending data in the this.output buffer.
while (this.output.length) {
if (!this.connection.writable) { //when not ready to send
this._buffer(data, encoding); //----------> save data into internal buffer
return false;
}
var c = this.output.shift();
var e = this.outputEncodings.shift();
this.connection.write(c, e);
}
// Directly write to socket.
return this.connection.write(data, encoding);
} else if (this.connection && this.connection.destroyed) {
// The socket was destroyed. If we're still trying to write to it,
// then we haven't gotten the 'close' event yet.
return false;
} else {
// buffer, as long as we're not destroyed.
this._buffer(data, encoding);
return false;
}
};