Потоковый файл через SFTP-соединение с клиентом

Я пишу сервер Node Express, который подключается через sftp к хранилищу файлов. Я использую пакет ssh2-sftp-client.

Для извлечения файлов у него есть функция get со следующей сигнатурой:

get(srcPath, dst, options)

Аргумент dst должен быть либо строкой, либо a writable stream, which will be used as the destination for a stream pipe.

Я хотел бы избежать создания файлового объекта на моем сервере и вместо этого передать файл на мой клиент, чтобы сэкономить потребление памяти, как описано в этом статья. Я попытался сделать это с помощью следующего кода:

const get = (writeStream) => {
    sftp.connect(config).then(() => {
        return sftp.get('path/to/file.zip', writeStream)
    });
};

app.get('/thefile', (req, res) => {
    get(res); // pass the res writable stream to sftp.get   
});

Однако это приводит к сбою моего сервера узла из-за необработанного отклонения обещания. Возможно ли то, что я пытаюсь? Должен ли я сначала сохранить файл на моем сервере перед отправкой клиенту? Я проверил документацию/примеры для рассматриваемого пакета sftp, но не могу найти пример того, что я ищу.


person CSharp    schedule 04.04.2019    source источник
comment
Не могли бы вы также добавить трассировку стека? Какое обещание выдает ошибку?   -  person Manuel Spigolon    schedule 04.04.2019
comment
Я предлагаю вам добавить отсутствующий обработчик отказа для обработки ошибки. Например: get(res).catch( (error) => { console.log(error)});   -  person Marcus    schedule 04.04.2019
comment
Спасибо! Я последовал вашему совету и в конце концов обнаружил, что это обещание внутри функции get было выброшено, потому что я не вызывал end в соединении, согласно моему ответу.   -  person CSharp    schedule 05.04.2019


Ответы (1)


Я нашел ошибку, и это глупо с моей стороны. Я забыл разорвать соединение sftp. Когда этот метод вызывался во второй раз, он выдавал исключение при повторной попытке подключения. Если кто-то окажется в такой же ситуации, не забудьте разорвать соединение, как только вы закончите с ним, следующим образом:

const get = (writeStream) => {
    sftp.connect(config).then(() => {
        return sftp.get('path/to/file.zip', writeStream);
    }).then(response => {
      sftp.end();
      resolve(response);
    });

};
person CSharp    schedule 05.04.2019