Частичный ответ в Node.js на Heroku

У меня есть очень простой код Node.js, который я хочу выдавать в виде фрагментированных ответов. Код является:

const WAIT = 500;
const records = [...];

function getList(req, res, url) {
    var list = records.slice().map(rec => JSON.stringify(rec) + "\n");
    var len = list.reduce((size, cur) => { size += Buffer.byteLength(cur); return size; }, 0);

    function next() {
        var cur = list.shift();
        if(!cur) {
            res.end();
            return;
        }

        res.write(cur);

        setTimeout(next, WAIT);
    }

    res.writeHead(200, {
        "Access-Control-Allow-Origin": "*",
        "Content-Type": "application/x-ndjson",
        "Content-Length": len.toString(),
        "X-Accel-Buffering": "no"
    });

    setTimeout(next, WAIT);
}

const PORT = process.env.PORT || 8080;
require("http").createServer(getList).listen(PORT);

Это должно записать эти данные как куски ndjson, пока массив не будет очищен.

Локально и в общем VPS это работает как ожидалось. На Heroku он не выпускает куски потоковым способом, а скорее выкидывает их все в конце.

У кого-нибудь есть представление о том, что я могу делать неправильно?

1 ответ

Решение

После раздела комментариев - установка Transfer-Encoding: Chunked заголовок явно решил эту проблему. Digital Ocean может делать что-то умное с чанкингом, в то время как вам нужно явно указать это в Heroku.

Документация по заголовку: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding

Другая потенциальная проблема, почему это может происходить в вашей системе: https://github.com/expressjs/compression/issues/56 (Если вы используете более старую версию expressjs - очистка ответа содержала ошибку)

Другие вопросы по тегам