米脂
2018-11-23 18:15:18
代碼var http = require('http');var server = http.createServer().listen(4000);
server.on('close', function () { console.log('close event', Date.now());
});
server.on('request', function (req, res) { console.log('request', Date.now());
server.close(function () { console.log('server closed!', Date.now());
});
res.end('res ok');
})描述為什么使用了 server.close(),卻不能觸發 close 事件?看了下 HTTP API 描述:停止服務端接收新的連接。以及 TCP API 描述:使服務器停止接收新連接,只保持現存的連接。這個函數是異步的,當所有連接斷開時,服務器關閉并且發出'close'事件...原來 server.close() 只是使服務器停止接收新連接,并沒有直接操作關閉服務器。只有當所有連接都斷開的時候,服務器才會處于關閉狀態并且發射 close 事件。但是,代碼改成延遲調用卻可以直接關閉服務器(當然,得在5秒內建立一個HTTP連接)。問題如果按照 API 中的描述,close()方法只是 停止服務端接收新的連接。那么,為什么改為后面這種方式卻可以直接關閉服務器?
1 回答

寶慕林4294392
TA貢獻2021條經驗 獲得超8個贊
api 的描述是正確的。只是你測試的時候理解錯了,兩種關閉 http 服務最終都會關閉,只是運行邏輯不同。
運行過程
代碼 1 會一直等待你建立 http 連接不關閉,直到你請求 1 次 http 連接,然后會在這次請求后的 2 分鐘后才關閉 http 服務。
代碼 2 會等待你 5 秒鐘,如果 5 秒之內你沒有建立連接,會直接關閉 http 服務。如果 5 秒之內你請求 1 次 http 連接,然后會在這次請求后的 2 分鐘后才關閉 http 服務。
運行過程的原因
原來 server.close() 只是使服務器停止接收新連接,并沒有直接操作關閉服務器。只有當所有連接都斷開的時候,服務器才會處于關閉狀態并且發射 close 事件。
問題在于什么時候算所有連接都斷開
?
當你執行 res.end('res ok'); 的時候,http 連接并沒有關閉,因為你的請求的 Connection
是 keep-alive
,這個時候只是 http 服務返回數據,瀏覽器渲染頁面,http 連接仍然是開啟狀態,然后如果你 2 分鐘內沒有新的請求,這次 http 連接才關閉。2 分鐘是 http 服務(不是 http 請求)默認的 timeout。
soonfy
添加回答
舉報
0/150
提交
取消