搜索

首页  >  问答  >  正文

javascript - 关于 http.Server 类的 close() 方法的疑问◔ ‸◔?

代码

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()方法只是 停止服务端接收新的连接。那么,为什么改为后面这种方式却可以直接关闭服务器?

为情所困为情所困2752 天前746

全部回复(1)我来回复

  • PHPz

    PHPz2017-05-16 13:44:34

    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

    回复
    0
  • 取消回复