Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 为什么NodeJS http服务器在超时时关闭套接字而没有响应?_Node.js_Express_Httpserver_Nginx Reverse Proxy - Fatal编程技术网

Node.js 为什么NodeJS http服务器在超时时关闭套接字而没有响应?

Node.js 为什么NodeJS http服务器在超时时关闭套接字而没有响应?,node.js,express,httpserver,nginx-reverse-proxy,Node.js,Express,Httpserver,Nginx Reverse Proxy,给定超时为10秒的NodeJS http服务器: const httpServer = require('http').createServer(app); httpServer.timeout = 10 * 1000; 超时时,Postman显示此消息,但不显示任何响应代码: Error: socket hang up Warning: This request did not get sent completely and might not have all the required s

给定超时为10秒的NodeJS http服务器:

const httpServer = require('http').createServer(app);
httpServer.timeout = 10 * 1000;
超时时,Postman显示此消息,但不显示任何响应代码:

Error: socket hang up
Warning: This request did not get sent completely and might not have all the required system headers
如果NodeJS服务器位于nginx反向代理之后,nginx将返回502响应(
从上游读取响应头时,上游连接过早关闭)。但这里它只是在localhost上运行的NodeJS/express。人们仍然希望得到正确的http响应

根据,这是预期的行为,套接字被简单地销毁

在使用nginx反向代理的体系结构中,服务器通常只销毁套接字而不向代理发送超时响应吗?

您正在设置。套接字超时可防止可能希望挂起您的连接以拒绝您的客户端滥用。它还有其他好处,比如确保一定水平的服务(尽管当你是客户时,这些好处往往更为重要)

它使用套接字超时而不是发送
408
状态代码(请求超时)的原因是,可能已经为成功的消息发送了状态代码

如果您想在后端实现响应超时并优雅地处理它,您可以自己超时响应。注意,您可能应该使用
408
来响应
502
用于http代理(nginx)等网关,用于指示下游连接失败

下面是一个简单的strawman实现

const httpServer = require('http').createServer((req, res) => {
    setTimeout(()=>{
        res.statusCode = 200;
        res.statusMessage = "Ok";
        res.end("Done"); // I'm never called because the timeout will be called instead;
    }, 10000)
});

httpServer.on('request', (req, res) => {
    setTimeout(()=>{
        res.statusCode = 408;
        res.statusMessage = 'Request Timeout';
        res.end();
    }, 1000)
});

httpServer.listen(8080);
你在设定目标。套接字超时可防止可能希望挂起您的连接以拒绝您的客户端滥用。它还有其他好处,比如确保一定水平的服务(尽管当你是客户时,这些好处往往更为重要)

它使用套接字超时而不是发送
408
状态代码(请求超时)的原因是,可能已经为成功的消息发送了状态代码

如果您想在后端实现响应超时并优雅地处理它,您可以自己超时响应。注意,您可能应该使用
408
来响应
502
用于http代理(nginx)等网关,用于指示下游连接失败

下面是一个简单的strawman实现

const httpServer = require('http').createServer((req, res) => {
    setTimeout(()=>{
        res.statusCode = 200;
        res.statusMessage = "Ok";
        res.end("Done"); // I'm never called because the timeout will be called instead;
    }, 10000)
});

httpServer.on('request', (req, res) => {
    setTimeout(()=>{
        res.statusCode = 408;
        res.statusMessage = 'Request Timeout';
        res.end();
    }, 1000)
});

httpServer.listen(8080);

谢谢,请您详细说明“状态码可能已经发送成功的消息。”?根据我的理解,如果已经发送了响应,套接字就不会超时。客户端可能会发出请求,然后再也不会尝试读取响应,从而保持连接。响应首先发送状态代码。(请参阅这些以获得良好的概述)。因此,您无法关闭插座并更改已通过导线发送的状态。在HTTP1.x中,先是状态,然后是标题,然后是正文。维基百科上有一篇关于不同DDOS攻击的好文章。其中一个是,在其他类似的攻击中,通过超时底层套接字在一定程度上减轻了攻击,但无法在HTTP层本身进行防御。如果我没有弄错的话,
setTimeout
的回调仅在请求超时时调用,而不是在keepalive超时时调用。在这两种情况下套接字都会被破坏,但只有在第一种情况下才会发送代码示例中的
408
。因此,这与Slowloris攻击无关,并且不可能已经发送响应,或者我错了吗?正确,setTimeout只是用于超时请求,但它本身并不处理套接字超时。如果需要,您可以通过抓取请求的套接字并为
on:timeout
事件添加自己的处理程序来处理该问题,但是您仍然应该确保关闭套接字。您是对的,如果套接字超时小于这两个值中的任何一个,您将得到相同的旧套接字超时,因此套接字超时应该大于您的请求超时。套接字超时只有在出现不稳定的情况下才会发生。谢谢,请您详细说明“状态码可能已经发送了一条成功的消息。”?根据我的理解,如果已经发送了响应,套接字就不会超时。客户端可能会发出请求,然后再也不会尝试读取响应,从而保持连接。响应首先发送状态代码。(请参阅这些以获得良好的概述)。因此,您无法关闭插座并更改已通过导线发送的状态。在HTTP1.x中,先是状态,然后是标题,然后是正文。维基百科上有一篇关于不同DDOS攻击的好文章。其中一个是,在其他类似的攻击中,通过超时底层套接字在一定程度上减轻了攻击,但无法在HTTP层本身进行防御。如果我没有弄错的话,
setTimeout
的回调仅在请求超时时调用,而不是在keepalive超时时调用。在这两种情况下套接字都会被破坏,但只有在第一种情况下才会发送代码示例中的
408
。因此,这与Slowloris攻击无关,并且不可能已经发送响应,或者我错了吗?正确,setTimeout只是用于超时请求,但它本身并不处理套接字超时。如果需要,您可以通过抓取请求的套接字并为
on:timeout
事件添加自己的处理程序来处理该问题,但是您仍然应该确保关闭套接字。您是对的,如果套接字超时小于这两个值中的任何一个,您将得到相同的旧套接字超时,因此套接字超时应该大于您的请求超时。套接字超时只有在发生不稳定的事情时才会发生。