node.JS HTTP服务器的正常关闭

2admgd59  于 2023-03-17  发布在  Node.js
关注(0)|答案(4)|浏览(186)

这是我正在开发的一个简单的Web服务器

var server = require("http").createServer(function(req,resp) {
    resp.writeHead(200,{"Content-Type":"text/plain"})
    resp.write("hi")
    resp.end()
    server.close()
})
server.listen(80, 'localhost')
// The shortest webserver you ever did see! Thanks to Node.JS :)

除了keep-alive之外,其他功能都很好。当第一个请求进来时,server.close会被调用。但是这个过程并没有结束。实际上,TCP连接仍然是打开的,这允许另一个请求通过,这是我试图避免的。
如何关闭现有的保持活动连接?

omqzjyyz

omqzjyyz1#

您可以控制连接的空闲超时,以便设置保持活动状态的连接保持打开的时间。例如:

server=require('http').createServer(function(req,res) {
    //Respond
    if(req.url.match(/^\/end.*/)) {
        server.close();
        res.writeHead(200,{'Content-Type':'text/plain'});
        res.end('Closedown');
    } else {
        res.writeHead(200,{'Content-Type':'text/plain'});
        res.end('Hello World!');
    }
}).listen(1088);
//Set the idle timeout on any new connection
server.addListener("connection",function(stream) {
    stream.setTimeout(4000);
});

我们可以用netcat测试一下:

ben@quad-14:~/node$ echo -e "GET /test HTTP/1.1\nConnection: keep-alive\n\n" | netcat -C -q -1 localhost 1088
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: keep-alive
Transfer-Encoding: chunked

c
Hello World!
0
  • 一月一日 *

现在我们可以展示关闭服务器的工作原理:在所有空闲连接都被丢弃之后,服务器退出:

ben@quad-14:~/node$ echo -e "GET /end HTTP/1.1\nConnection: keep-alive\n\n" | netcat -C -q -1 localhost 1088
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: keep-alive
Transfer-Encoding: chunked

9
Closedown
0
  • 一米一分一秒 *
ej83mcc0

ej83mcc02#

可以在响应回调中调用request.connection.destroy(),这将关闭请求连接。
它还将结束您的进程,因为没有什么可做的,最终结果与在此处调用process.exit()相同。

2ic8powd

2ic8powd3#

如果您要关闭服务器作为进程正常关闭的一部分,您只需要执行以下操作:

var server = require('http').createServer(myFancyServerLogic);

server.on('connection', function (socket) {socket.unref();});
server.listen(80);

function myFancyServerLogic(req, res) {
    req.connection.ref();

    res.end('Hello World!', function () {
        req.connection.unref();
    });
}

基本上,服务器使用的套接字只会在它们实际服务于请求时才让进程保持活动状态,而它们只是无所事事(因为Keep-Alive连接),只要没有其他东西使进程保持活动状态,调用server.close()就会关闭进程。如果您需要在服务器关闭后执行其他操作,作为正常关闭的一部分,您可以连接到process.on('beforeExit', callback)来完成正常的关机过程。

z9smfwbn

z9smfwbn4#

如何关闭现有的保持活动连接?
从节点18.2.0开始,您可以使用closeAllConnections()closeIdleConnections()方法中的任何一种:

server.closeAllConnections()

添加于:v18.2.0
关闭连接到此服务器的所有连接。

server.closeIdleConnections()

添加于:v18.2.0
关闭连接到此服务器的所有未发送请求或等待响应的连接。
例如,这对于HTTP服务器的单元测试非常有用:

import assert from 'node:assert/strict';
import http from 'node:http';
import test from 'node:test';

test.describe(() => {
  const server = http.createServer((request, response) => {
    response.statusCode = 200;
    response.setHeader('Content-Type', 'text/plain');
    response.setHeader('Content-Length', '12');
    response.end('hello, world');
  });
  server.listen(8000, 'localhost')

  test.after(() => {
    server.closeIdleConnections();
    server.close();
  });

  test.test(async () => {
    const response = await fetch('http://localhost:8000/');
    assert.equal(response.status, 200);
    assert.equal(response.headers.get('Content-Type'), 'text/plain');
    assert.equal(response.headers.get('Content-Length'), '12');
    assert.equal(await response.text(), 'hello, world');
  });
});

相关问题