javascript - 關於 http.Server 類別的 close() 方法的疑問◔ ‸◔?
为情所困
为情所困 2017-05-16 13:42:34
0
1
770

程式碼

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連線)。

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());
  res.end('res ok');
})

function closeServer() {
  server.close(function () {
    console.log('server closed!', Date.now());
  });
}

setTimeout(function () {
  closeServer();
}, 5000);

問題

如果依照 API 中的描述,close()方法只是 停止服務端接收新的連線。那麼,為什麼改為後面這種方式卻可以直接關閉伺服器?

为情所困
为情所困

全部回覆(1)
PHPzhong

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 連接並沒有關閉,因為你的請求的Connectionkeep-alive,這個時候只是http 服務返回數據,瀏覽器渲染頁面,http 連接仍然是開啟狀態,然後如果你2 分鐘內沒有新的請求,這次http 連線才關閉。 2 分鐘是 http 服務(不是 http 請求)預設的 timeout。

soonfy

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板