Stream from Nodejs express app not being read in chunks by client

Viewed 146

My web app client hits my Node API which runs a shell script in a child process. The script can take a long time to run, but outputs text along the way. My goal is for my web app to display the progress messages as they are emitted from the child process. After triggering the fetch, my API console is showing the intermittent "write data" logs with text from the child process as expected. However, the Chrome console where I initiate the fetch only displays a single "Received" log with the entire text buffer when the request is complete.

Maybe I'm misunderstanding how this works. Can I actually do what I'm trying to do?

SERVER CODE

app.put('/api/action', (req, res) => {
  const spawn = require('child_process').spawn;
  const child = spawn('./my-shell-script', [], { cwd: path.resolve(__dirname, '../scripts/'), shell: true });

  res.setHeader('Content-Type', 'text/html; charset=utf-8');
  res.setHeader('Transfer-Encoding', 'chunked');

  child.stdout.on('data', data => {
    console.log('write data', data.toString());
    res.write(data.toString());
  });

  child.stderr.on('data', error => {
    console.log('write error', error.toString());
    res.write(error.toString());
  });

  child.on('error', s => console.error('error', s));

  child.on('close', (code) => {
    console.log(`action exited with code ${code}`);
    if (code !== 0) {
      res.status(500);
    }

    res.end();
  });
});

CLIENT CODE

const response = await wpeFetch(`/api/action`, {
  method: 'PUT',
  headers: new Headers({
    'Content-Type': 'application/json'
  }),
  body: JSON.stringify({
    scope: site,
    action,
  })
});

const reader = response.body.pipeThrough(new window.TextDecoderStream()).getReader();

while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  console.log('Received', value);
}

console.log('Response fully received');
0 Answers
Related