question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Sending chunked responses

See original GitHub issue

I 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:closed
  • Created 8 years ago
  • Reactions:1
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
hawkengcommented, Nov 4, 2018

I want to achieve the same as @lukas-zech-software so far no luck. Any updates on this?

0reactions
jaylicommented, Oct 3, 2020

Here are some demos for this issue. Maybe it will help you.

https://github.com/jayli/koa-stream-await-call-error

Read more comments on GitHub >

github_iconTop Results From Across the Web

Transfer-Encoding - HTTP - MDN Web Docs
Chunked encoding is useful when larger amounts of data are sent to the client and the total size of the response may not...
Read more >
Chunked transfer encoding - Wikipedia
In chunked transfer encoding, the data stream is divided into a series of non-overlapping "chunks". The chunks are sent out and received independently...
Read more >
Sending an HTTP request or response with chunked transfer ...
Specify CHUNKING(CHUNKYES) to tell CICS that it is a chunk of a message. · Use the FROM option to specify the first chunk...
Read more >
HTTP Chunking - Oracle
HTTP 1.1 supports chunked encoding, which allows HTTP messages to be broken up into several parts. Chunking is most often used by the...
Read more >
How to send chunked transfer-encoded hyper response?
Chunked transfer encoding is part of HTTP/1.1, and not part of HTTP/2. When a handler responds with a chunked stream, Hyper will do...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found