繁体   English   中英

nodejs 服务器如何处理来自同一客户端和不同客户端的多个并发请求?

[英]How does nodejs server handles multiple concurrent request from same client and different client?

我正在测试以下代码:

const http = require('http');

const server = http.createServer((req, res)=> {

    const url = req.url;

    if(url === '/'){
        setTimeout(() => {
            res.write('<html>');
            res.write('<head><title>Enter Message</title></head>');
            res.write('<body><form action="/message" method="POST"><input type="text" name="message"><button type="submit">Send</button></form></body>');
            res.write('</html>');

            return res.end();

        }, 10000);

        console.log('Hi');
    }
});

server.listen(3000);

场景 1:我所做的是打开浏览器窗口并运行 localhost:3000,Hi 立即打印,10 秒后在浏览器中收到响应,同时(在控制台打印 Hi 和在浏览器选项卡中收到响应之间),我打开一个不同的浏览器选项卡并再次转到 loaclhost:3000,我希望再次打印“嗨”,但是它仅在第一个选项卡中收到响应后才打印。

场景 2:我重复上述相同的操作,但是在同一浏览器窗口中打开第二个选项卡的位置,我选择在隐身模式或与我的笔记本电脑处于同一网络的设备上打开它,然后我没有看到任何延迟,嗨,是立即打印来自隐身窗口的请求,而第一个浏览器的响应仍应收到?

我在这里想念什么? 如何修复这种行为?

我在这里想念什么?

这是由浏览器引起的,而不是由 node.js 引起的,是浏览器的一个实现细节。 浏览器显然决定如果已经有一个对http://localhost:3000的请求已经在处理中,它不会发送另一个相同的请求,直到那个请求完成。 您已验证使用不同的浏览器会使问题消失,这与这是浏览器实现问题/功能一致。 此外,node.js 中没有任何行为会导致这种情况,因为您使用的是setTimeout() ,因此如果第二个请求到达,node.js 当然可以自由地开始处理它。

如果您可以在客户端或服务器计算机上运行某种网络间谍,您可以验证发送第二个 http 请求的准确时间,但我很确定您会发现浏览器直到第一个请求完成。

我可以想到浏览器可能会这样做的三个可能原因:

  1. 浏览器一次打开了对该主机的最大请求数。 每个浏览器都配置为一次对同一主机的最大请求数,但该限制肯定不止一个,因此必须有其他对该主机的打开请求才能成为这里的原因。
  2. 浏览器认为如果服务器响应特定请求的速度很慢,那么它不会帮助该服务器更快地向它发送另一个相同的请求。
  3. 浏览器希望第一个结果可以缓存,因此当它返回时,浏览器可能只能将该结果用于第二个请求。

如何修复这种行为?

在不久前的先前测试中,我能够通过向第二个请求添加一个查询字符串来解决这个问题,例如http://localhost:3000?num=2这使得它与第一个请求“不同”,并且浏览器没有阻止它。 您必须确保您的服务器仍在处理请求,即使它上面有查询字符串。

在 Chrome 中进行一些测试后

并且,使用您的服务器代码的变体剥离查询字符串,使其不受其影响,我已经验证如果两个浏览器窗口具有完全相同的 URL,但将查询字符串添加到第二个窗口将导致两者立即发送,因此这是一种可能的解决方法。

在 Firefox 中测试产生不同的结果

作为更多证据表明这与 node.js 本身无关,如果我在 Firefox 中重复相同的测试,则没有这种行为。 两个单独窗口中的两个相同请求都一个接一个地发送到 node.js,我立即看到两个console.log("Hi")语句。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM