最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - sending two responses for same request - Stack Overflow

programmeradmin4浏览0评论

In Node.js, suppose serving a request takes time. So upon receipt of the request the server wants to response back with "I revived your request and I will get back to you soon". Then once the processing the request is over, the server wants to, this time, get back to the client with the actual response . How can we do that? The code snippet below issues error ( connection closed or something ).

'use strict';
var http = require('http');
var numberOfRequests = 0;
http.createServer(function (request, responce) {
    request.n = numberOfRequests;
    console.log('Request number ' + numberOfRequests + ' recioved!');
    responce.writeHead(200);
    responce.write("soon we will get back to you for your request# " + request.n);
    responce.end();
    setTimeout(function () {
        responce.writeHead(200);
        responce.write("Responce to your request# " + request.n);
        console.log("Responce to the request# " + request.n);
        responce.end();
    }, 5000);

    numberOfRequests++;
}
).listen(8080);
console.log('listening ...');

In Node.js, suppose serving a request takes time. So upon receipt of the request the server wants to response back with "I revived your request and I will get back to you soon". Then once the processing the request is over, the server wants to, this time, get back to the client with the actual response . How can we do that? The code snippet below issues error ( connection closed or something ).

'use strict';
var http = require('http');
var numberOfRequests = 0;
http.createServer(function (request, responce) {
    request.n = numberOfRequests;
    console.log('Request number ' + numberOfRequests + ' recioved!');
    responce.writeHead(200);
    responce.write("soon we will get back to you for your request# " + request.n);
    responce.end();
    setTimeout(function () {
        responce.writeHead(200);
        responce.write("Responce to your request# " + request.n);
        console.log("Responce to the request# " + request.n);
        responce.end();
    }, 5000);

    numberOfRequests++;
}
).listen(8080);
console.log('listening ...');
Share Improve this question asked Oct 2, 2017 at 23:17 Waterfr VillaWaterfr Villa 1,3171 gold badge13 silver badges36 bronze badges 5
  • 1 you can't, the end. You only get one response per request using the HTTProtocol, so you'll just have to schedule more requests if the response is "not yet", or set up a direct socket connection so that the client and server can municate using a push notification protocol rather than the standard HTTP. – Mike 'Pomax' Kamermans Commented Oct 2, 2017 at 23:18
  • @Mike'Pomax'Kamermans please elaborate more – Waterfr Villa Commented Oct 2, 2017 at 23:20
  • There's nothing to elaborate: "No: HTTP does not let you send multiple responses. One request, which is considered handled when it gets one response". If you want to do more than that, you'll have to design either a RESTful architecture that works with that, or you need to use a different protocol that allows arbitrary munication like websockets. – Mike 'Pomax' Kamermans Commented Oct 2, 2017 at 23:23
  • Not to mention that you can use asynchronicity in the client to have the client do other stuff (like display a spinner) while it waits for a request to finish. The server can also be async so that if pleting the building of the response is slow, to handle other requests while waiting for previous responses to finish. – cowbert Commented Oct 2, 2017 at 23:33
  • Socket.io will be the good solution for this problem – Vishnu Mishra Commented Oct 3, 2017 at 1:12
Add a ment  | 

2 Answers 2

Reset to default 4

You can't send two responses to the same request. You can only send one fully formed response per request. That's the http specification.

The only work-arounds for your issue that I know of are:

  1. Use http in a flushed streaming mode. Here, you send part of the response, flush it out so you know it is sent and you have a special type of client on the other end that is reading partial responses and interpreting them (not the usual way that http responses are read and not what a browser does on its own).

  2. Use a websocket or socket.io connection to update the client with progress before you finally send the actual http response. The user would connect a socket.io connection, then make a long running http request, then receive regular progress on the socket.io connection, then receive the http response when it was done. This can be done simply in any web page without much difficulty. The only main problem to solve is you have to install a method of associated a webSocket or socket.io connection with an ining http connection (which can usually be done via a session cookie) so you know which webSocket or socket.io connection is associated with the http request that just arrives.

  3. Use some other server-push scheme to "push" the second response to the client.

  4. Implement client polling. Send an initial http response that instructs the client to check back in NN ms to see if there is more to the response. When the client checks back again NN ms later, you either have the final response for them and send it or you respond again tell them to to check back again in NN ms, etc...

You are looking for Server-Sent-Events (SSE), of course you can send chunked data, just don't call res.end() until the final piece of data is sent. And by the way, you can only send headers one time. See this example:

res.writeHead(200);
res.write("The first piece of data");
setTimeout(()=>{
    res.write("This piece of data will be sent in 1 second.");
    res.end("Ok, all data has be send, now close the connection.");
}, 1000);
发布评论

评论列表(0)

  1. 暂无评论