這是Node.js的end
實現:使用node.js HTTP,res.end()如何保證套接字的斷開連接?
OutgoingMessage.prototype.end = function(data, encoding) {
if (this.finished) {
return false;
}
if (!this._header) {
this._implicitHeader();
}
if (data && !this._hasBody) {
console.error('This type of response MUST NOT have a body. ' +
'Ignoring data passed to end().');
data = false;
}
var ret;
var hot = this._headerSent === false &&
typeof(data) === 'string' &&
data.length > 0 &&
this.output.length === 0 &&
this.connection &&
this.connection.writable &&
this.connection._httpMessage === this;
if (hot) {
// Hot path. They're doing
// res.writeHead();
// res.end(blah);
// HACKY.
if (this.chunkedEncoding) {
var l = Buffer.byteLength(data, encoding).toString(16);
ret = this.connection.write(this._header + l + CRLF +
data + '\r\n0\r\n' +
this._trailer + '\r\n', encoding);
} else {
ret = this.connection.write(this._header + data, encoding);
}
this._headerSent = true;
} else if (data) {
// Normal body write.
ret = this.write(data, encoding);
}
if (!hot) {
if (this.chunkedEncoding) {
ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
} else {
// Force a flush, HACK.
ret = this._send('');
}
}
this.finished = true;
// There is the first message on the outgoing queue, and we've sent
// everything to the socket.
if (this.output.length === 0 && this.connection._httpMessage === this) {
debug('outgoing message end.');
this._finish();
}
return ret;
};
來源:https://github.com/joyent/node/blob/master/lib/http.js#L645
顯然,連接僅僅是 「完成」 的時候output.length === 0
。
那麼,如果仍有數據等待寫入,並且接收客戶端由於某種原因對接收這些數據不利,那麼請求是否會結束?
我也看到了這樣的問題,當試圖結束由閃存上傳器發出的http請求時,結束無效。我結束了做以下,這有幫助:
res.end(failureJSON, 'utf8');
req.once('end', function _destroyConn() {
req.connection.destroy();
});
似乎很hackish。無論如何,req.connection.destroy
是否需要保證從插座斷開連接?
如果客戶聲稱連接保持活動會怎樣?我在考慮Flush命令沒有被調用,因爲客戶端正在阻止它(例如通過發送數據)。 – Tom
如果我正確閱讀,設置'res.shouldKeepAlive = false;'應該覆蓋任何客戶端設置。 – loganfsmyth
所以你的結論是,正確結束連接是執行以下序列? '''res.shouldKeepAlive = false; res.end();''' – Tom