Тайм-аут функции Firebase при передаче потока клиенту - PullRequest
0 голосов
/ 02 февраля 2019

На сервере я хочу преобразовать HTML в PDF, передать PDF обратно клиенту, а затем загрузить файл.

Изолированный - без использования Firebase Hosting или Functions - у меня простой узел/ Express Server со следующей конечной точкой POST (с использованием промежуточного программного обеспечения Body Parser):

app.post('/download', (req, res) => {
    res.writeHead(200, {
        'Content-Type': 'application/pdf',
        'Content-disposition': 'attachment; filename=Report.pdf'
    });

    const options = { format: 'letter' };

    pdf.create(req.body.template, options).toStream((err, stream) => {
         if (err) res.send(err);

         const watchdog = stream.pipe(res);

         watchdog.on('finish', () => {
             console.log('Finish event emitted');
             res.end();
         });
    });
});

Обратите внимание, что это должен быть маршрут POST - по причинам, выходящим за рамки этого вопроса.

На клиенте я довольно легко могу получить этот поток, создать URL-адрес Blob, а затем загрузить файл, программно щелкнув по тегу привязки:

const headers = new Headers();
headers.append('Content-Type', 'application/json'); 

const data = { template: '<h1>This is my data sent from the client!</h1>'};

fetch('/download', {
            method: "POST",
            mode: "cors",
            headers,
            body: JSON.stringify(data)
        })
        .then(response => response.body)
        .then(body => {
            const reader = body.getReader();
            return new ReadableStream({
                start(controller) {
                    return pump();
                    function pump() {
                        return reader.read().then(({ done, value }) => {
                            if (done) {
                                controller.close();
                                return;
                            }
                            controller.enqueue(value);
                            return pump();
                        })
                    }
                }
            })
        })
        .then(stream => new Response(stream))
        .then(response => response.blob())
        .then(blob => URL.createObjectURL(blob))
        .then(url => {
            const link = document.createElement('a');
            link.href = url;
            link.download = "Report.pdf";
            link.click();
        })
        .catch(err => console.log(err));

В моей изолированной среде тестирования это работает фантастически иЭто займет всего около трех секунд.

Когда я попытался перейти с моего тестового сервера на Firebase Cloud Functions, возникли проблемы.В Firebase Functions я использую точно такой же маршрут POST, я просто включаю CORS и устанавливаю экспорт:

const cors = require('cors');
app.use(cors({ origin: true })); // Will change in production.

// Exact same POST Route as above - no changes in code.

exports.app = functions.https.onRequest(app);

На клиенте я делаю точно такой же запрос Fetch POST, единственной дельтой являетсядругой URL:

fetch('https://us-central1-[my-project-id].cloudfunctions.net/app/download',{
    // Same code as above for client.
});

Однако при развертывании приложения я не получаю ответ, а иногда и время ожидания запроса.Сегодня я вызывал эту функцию всего несколько раз и все еще использовал свободную квоту.Даже использование return stream.pipe(res) не работает в функции.Я заметил, что все запросы истекают, и функция, кажется, продолжает вызывать себя, как если бы она была рекурсивной.

Я был бы очень признателен за любую помощь в понимании того, почему код отлично работает на моем собственном локальном сервере.с Node / Express, но не работает при переходе на Firebase Functions.

...