Записывать выходные данные процесса в ответ по мере их создания

У меня есть фоновый процесс, который генерирует много вывода. Я хочу отправить вывод клиенту, как только они станут доступны. Я ожидаю, что клиент отправит HTTP-запрос GET/POST, сервер откроет соединение и keeps it alive, затем сервер продолжит потоковую передачу данных по мере их появления.

Пример из реальной жизни. Когда вы запускаете тестовую команду или команду оболочки в AWS/Heroku/GoogleAppEngine, она показывает результат в реальном времени, как если бы команда выполнялась на моем локальном компьютере. Как они это делают?


Сервер. В этом образце сервера процесс генерирует сообщение каждую секунду.

function handleRequest (request, response) {
  for (let i = 0; i < 10; i++) {
    response.write('This is message.' + i)
    require('child_process').execSync("sleep 1")
  }
  response.end()
}


Клиент. Клиент должен получать данные по мере их поступления, т. е. по одному. Но на выходе, конечно, я ожидал, все данные собираются сразу и отправляются обратно клиенту.

request.put(formData)
       .on('data', function (data) {
         console.log(data.toString())
       })


Я новичок в NodeJS, но я надеюсь, что смогу вернуть какую-то форму writable stream обратно клиенту, и когда данные записываются в этот поток на стороне сервера, клиент получит их на своем конце?


person Rash    schedule 16.07.2017    source источник
comment
Я думаю, вы говорите о веб-сокетах   -  person Jarek Kulikowski    schedule 16.07.2017
comment
@JarekKulikowski Но это не веб-приложение, и я не хочу, чтобы мои клиенты продолжали отправлять запросы, чтобы узнать, доступны ли дополнительные данные. Так как объект response имеет метод on(), я подумал, что отправка данных порциями с сервера будет очень простой.   -  person Rash    schedule 16.07.2017
comment
В случае WebSockets клиент (браузер или другой сервер) открывает соединение и ожидает данных от сервера. Разница между протоколом WebSockets (ws://) и http:// заключается в том, что соединение ws:// остается открытым на неопределенный срок. Я использовал только WebSockets между браузером и WebServer, но, если я не ошибаюсь, было бы так же легко настроить его между двумя серверами узлов.   -  person Jarek Kulikowski    schedule 16.07.2017
comment
@JarekKulikowski Я подумываю о веб-сокетах, но перед этим я хочу понять, скажем, у меня есть огромный файл, поэтому я пишу на сервере fs.createReadStream() и передаю его на response, а на клиенте делаю request.on('data', callback). В этом сценарии данные разбиваются на части и доставляются клиенту as they are being read. Мой вопрос в том, как мой сценарий отличается от этого?   -  person Rash    schedule 16.07.2017
comment
Я не думаю, что это принципиально отличается, но я не думаю, что смогу ответить на этот вопрос, поскольку я никогда не перемещал большие объемы данных через WebSockets. Если вы соединяете две машины-узла как клиент‹-›сервер, то WebSockets не обязательно помогут, потому что вы можете сделать то же самое через http более стабильным способом. Я думаю, что эта ссылка может помочь stackoverflow.com/questions/39335686/   -  person Jarek Kulikowski    schedule 16.07.2017