Sending chunked responses
See original GitHub issueI try to implement a long polling mechanism using chunked headers to keep the connection alive.
Basically I run a very long async operation on the server, and while waiting for this operation to finish, I want to sent data over the connection to keep it alive. This behaviour is necessary to keep Heroku from shutting down the connection after 30 seconds
Therefore I assigned a stream to this.body
and push spaces to the stream every 2 seconds, expecting that these will be immediately be sent to the client via a chunked transfer response.
But the response is not sent until the stream is flushed, then sending the whole data at once.
Currently I solved it like this
//Send the headers
//Tell the client everything is fine and that we will send JSON
//Set the headers manually so that koa does not try to set them, when the response is flushed
this.status = 200;
this.type = 'application/json';
//Create a ChunkedResponseStream to send a chunked response
const chunkedResponse = new stream.Readable();
chunkedResponse._read=()=>{};
chunkedResponse.pipe(this.res);
//Write a space character to the response every second to keep the connection alive
//the space will not invalidate the JSON that will be sent later
interval = setInterval(()=> {
chunkedResponse.push(' ');
}, 2000);
try {
const result = yield expensiveOperation();
//Write the serialized JSON to the stream
chunkedResponse.push(JSON.stringify({result: result}));
} catch (e) {
//As it is too late to set the header to an error state, we log it and send an error message to the client
console.error('Error while calling "expensiveOperation"', e);
chunkedResponse.push(JSON.stringify({error: 'Error while calling "expensiveOperation"'}));
} finally {
//Once the data is there, clear the interval
clearInterval(interval);
//End the stream
chunkedResponse.push(null);
}
Is there any built in mechanic that I could use for this kind of operation?
Piping to this.res
does not seem like the koa-way of doing this
I understand that there are difficulties in unwinding the middleware stack if headers cannot be set anymore, as they have been already sent with the first chunk, but is there any built in possibility to support chunked transfers or telling all following middle ware, that the headers are blocked?
Issue Analytics
- State:
- Created 8 years ago
- Reactions:1
- Comments:12 (5 by maintainers)
Top GitHub Comments
I want to achieve the same as @lukas-zech-software so far no luck. Any updates on this?
Here are some demos for this issue. Maybe it will help you.
https://github.com/jayli/koa-stream-await-call-error