Я пытаюсь передать произвольно большой объем данных по HTTP из подпроцесса, используя node. Мой полный код находится здесь, и основной фрагмент:

  res.writeHead(200, {
    'Content-Type': 'application/octet-stream',
    'Content-Disposition': 'attachment;filename=osm_export_' +
      ((north + south) / 2) + '_' + ((east + west) / 2) + '.pbf'
    });

  // run vex
  var proc = spawn(cmd, [dbname, south, west, north, east, '-']);

  // stream chunks
  proc.stdout.pipe(res);

Приблизительно после 40 МБ (где-то между 40 000 000 и 42 000 000 байт) поток прерывается, и запрос никогда не завершается. Я не могу установить заголовок Content-Length, потому что я не знаю, сколько данных будет производить команда, пока она не будет выполнена. Мне интересно, не является ли это опустошением буфера; рассматриваемая команда извлекает данные из базы данных и записывает поток, который может быть медленнее, чем соединение между моим компьютером и моим сервером. Я подозреваю это, потому что я заменил код на это:

var http = require('http');
var spawn = require('child_process').spawn;

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'application/octet-stream'});

  var proc = spawn('head', ['-c', '500000000', '/dev/zero']);

  proc.stdout.pipe(res);
}).listen(8181, '127.0.0.1');

Который передает 500 МБ нулевых данных, и все работало нормально. Есть ли какой-то тайм-аут и т. Д., Который мне нужно установить?

2
mattwigway 11 Ноя 2014 в 18:43

2 ответа

А, нашел проблему. Это может или не может быть полезным для других. Я ничего не делал с потоком процесса stderr, а внутренний процесс записывает много информации о состоянии в stderr. Буфер внутри узла где-то заполнялся, а затем он давал сбой. Изменение строки создания процесса на

  var proc = spawn(cmd, [dbname, south, west, north, east, '-'], {stdio: ['ignore', 'pipe', 'ignore']});

Решил проблему. Спасибо всем, кто помог!

2
mattwigway 11 Ноя 2014 в 20:41

Попробуйте настроить заголовок HTTP Content-Length и установить его значение в соответствии с размером данных, которые вы используете в ответе.

0
Morrisda 11 Ноя 2014 в 18:51
Спасибо за быстрый ответ. К сожалению, это последовательное чтение файла и его фильтрация, поэтому я заранее не знаю длину содержимого; Я должен был упомянуть об этом в вопросе.
 – 
mattwigway
11 Ноя 2014 в 18:53
Я не знаю, как помочь, это единственное возможное решение, которое я нашел, и я нашел его здесь: stackoverflow.com/questions/3905473/…. до свидания
 – 
Morrisda
11 Ноя 2014 в 19:00