如果我有以下代码每10ms重复发送一次数据到客户端:
setInterval(function() {
res.write(somedata);
}, 10ms);
如果客户端收到数据的速度很慢,会发生什么?
服务器是否会出现内存不足错误?
编辑:
实际上连接保持活动,服务器无休止地发送jpeg数据(HTTP multipart / x-mixed-replace header + body + header + body .....)
因为node.js response.write是异步的,所以
所以一些用户猜测它可能会将数据存储在内部缓冲区中并等到低层告诉它可以发送,
所以内部缓冲区会增长,我是对的吗?
如果我是对的,那么如何解决这个问题呢?
问题是node.js在为单次写入调用发送数据时不会通知我
换句话说,我不能告诉用户这种方式理论上没有“内存不足”的风险。以及如何解决它。
更新的
通过关键字" drain" user568109给出的事件,我研究了node.js的来源,并得出结论:
它确实会导致"内存不足"错误。我应该检查response.write(...)=== false的返回值,然后处理" drain"回复事件。
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;
}
};
答案 0 :(得分:2)
一些问题:
如果通过http发送它不是一个好主意。如果请求未在指定的时间内完成,则浏览器可将其视为超时。服务器也将关闭闲置太久的连接。如果客户端无法跟上,则超时几乎可以肯定。
10ms的setInterval也受到一些限制。这并不意味着它会在每10ms后重复,10ms是重复之前等待的最小值。它会比您设置间隔的速度慢。
假设你有机会用数据重载响应,那么在某些时候服务器将终止连接并根据设置的限制由413 Request Entity Too Large
响应。
Node.js具有单线程架构,最大内存限制约为1.7 GB。如果 设置 您的上述服务器限制太高且有多个传入连接,则会出现process out of memory
错误。
因此,如果有适当的限制,它将提供超时或请求太大。 (并且您的程序中没有其他错误。)
<强>更新强>
您需要使用drain
事件。 http响应是可写流。它有自己的内部缓冲区。当清空缓冲器时,触发排出事件。您应该深入了解有关流的更多信息。这不仅可以帮助你。您可以在网上找到有关流的几种资源。