简体   繁体   English

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

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

I am testing the below code:我正在测试以下代码:

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);

Scenario 1: What i do is i open a browser window and run localhost:3000, Hi is printed right away and after 10 seconds response is received in browser, meanwhile (between printing Hi in console and response is received in browser tab), i open a different browser tab and go to loaclhost:3000 again, i am expecting 'Hi' to be printed again, however it is only printed after the response has been received in first tab.场景 1:我所做的是打开浏览器窗口并运行 localhost:3000,Hi 立即打印,10 秒后在浏览器中收到响应,同时(在控制台打印 Hi 和在浏览器选项卡中收到响应之间),我打开一个不同的浏览器选项卡并再次转到 loaclhost:3000,我希望再次打印“嗨”,但是它仅在第一个选项卡中收到响应后才打印。

Scenario 2: I repeat the same as above however in the place of opening 2nd tab in same browser window i choose to open it in incongnito or on a device in the same network as my laptop, then i do not see any delay, Hi is printed right away for the request from incongnito window while the response for the 1st browser was still due to get received?场景 2:我重复上述相同的操作,但是在同一浏览器窗口中打开第二个选项卡的位置,我选择在隐身模式或与我的笔记本电脑处于同一网络的设备上打开它,然后我没有看到任何延迟,嗨,是立即打印来自隐身窗口的请求,而第一个浏览器的响应仍应收到?

What am i missing here to understand?我在这里想念什么? How can this behaviour be fixed?如何修复这种行为?

What am i missing here to understand?我在这里想念什么?

This is caused by the browser, not by node.js and is an implementation detail of the browser.这是由浏览器引起的,而不是由 node.js 引起的,是浏览器的一个实现细节。 The browser is apparently deciding that if there is already a request for http://localhost:3000 in process already, it won't send another identical request until that one finishes.浏览器显然决定如果已经有一个对http://localhost:3000的请求已经在处理中,它不会发送另一个相同的请求,直到那个请求完成。 You have verified that using a different browser makes the issue disappear which is consistent with this being a browser implementation issue/feature.您已验证使用不同的浏览器会使问题消失,这与这是浏览器实现问题/功能一致。 Further, there is no behavior in node.js that would cause this because you are using setTimeout() , so node.js is certainly free to begin processing the second request if it arrived.此外,node.js 中没有任何行为会导致这种情况,因为您使用的是setTimeout() ,因此如果第二个请求到达,node.js 当然可以自由地开始处理它。

If you can run some sort of network spy on either the client or server computers, you can verify the precise timing of when the second http request is sent, but I'm pretty sure you will find that the browser isn't sending it until the first request finishes.如果您可以在客户端或服务器计算机上运行某种网络间谍,您可以验证发送第二个 http 请求的准确时间,但我很确定您会发现浏览器直到第一个请求完成。

I can think of three possible reasons why a browser might do this:我可以想到浏览器可能会这样做的三个可能原因:

  1. The browser already has a max number of requests to that host open at once.浏览器一次打开了对该主机的最大请求数。 Browser are each configured for a max number of requests to the same host at a time, but that limit is definitely more than one so there would have to be other open requests to that host for this to be the cause here.每个浏览器都配置为一次对同一主机的最大请求数,但该限制肯定不止一个,因此必须有其他对该主机的打开请求才能成为这里的原因。
  2. The browser figures if a server is slow to respond to a specific request, then it won't help that server go any faster to send it another identical request.浏览器认为如果服务器响应特定请求的速度很慢,那么它不会帮助该服务器更快地向它发送另一个相同的请求。
  3. The browser is hoping that the first result might be cacheable so when it comes back, the browser may just be able to use that result for the 2nd request.浏览器希望第一个结果可以缓存,因此当它返回时,浏览器可能只能将该结果用于第二个请求。

How can this behavior be fixed?如何修复这种行为?

In previous tests a little while ago, I was able to work around it by adding a query string to the second request such as http://localhost:3000?num=2 which makes it a "different" request than the first one and the browser didn't hold it back.在不久前的先前测试中,我能够通过向第二个请求添加一个查询字符串来解决这个问题,例如http://localhost:3000?num=2这使得它与第一个请求“不同”,并且浏览器没有阻止它。 You would have to make sure your server was still processing the request even if it had a query string on it.您必须确保您的服务器仍在处理请求,即使它上面有查询字符串。

After Some Testing in Chrome在 Chrome 中进行一些测试后

And, using a variant of your server code that strips off the query string so that it isn't influenced by that, I've verified that Chrome will hold off sending the second request until the first one finishes if the two browser windows have the exact same URL, but adding a query string to the second window will cause both to get sent immediately so that is a possible work-around.并且,使用您的服务器代码的变体剥离查询字符串,使其不受其影响,我已经验证如果两个浏览器窗口具有完全相同的 URL,但将查询字符串添加到第二个窗口将导致两者立即发送,因此这是一种可能的解决方法。

Test in Firefox Yields Different Results在 Firefox 中测试产生不同的结果

As more evidence that this has nothing to do with node.js itself, if I repeat the same test in the Firefox, there is no such behavior.作为更多证据表明这与 node.js 本身无关,如果我在 Firefox 中重复相同的测试,则没有这种行为。 Two identical requests in two separate windows are both sent to node.js one right after the other and I see the two console.log("Hi") statements right away for both.两个单独窗口中的两个相同请求都一个接一个地发送到 node.js,我立即看到两个console.log("Hi")语句。

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

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