Streaming http response
某些時候,我們會希望在Server端執行比較久的回應結果可以持續得回傳回來。在express中,可以透過res.write()來持續回傳結果,直到回傳完成,再結束這個連線... 下面是express中的片段範例... 其中"/exec"這個route是在本地端執行child_process.exec(),然後將結果回傳...
範例
app.use('/exec', function(req, res){
exec(function(d, t){
res.write(d);
if(t && t == 'end') res.end('\ndone...');
});
});
function exec(fn){
const spawn = require('child_process').spawn;
const ls = spawn('bash', ['/tmp/test.sh']);
ls.stdout.on('data', (data) => {
fn(`stdout: ${data}`, 'stdo-data');
});
ls.stderr.on('data', (data) => {
fn(`stderr: ${data}`, 'stde-data');
});
ls.on('close', (code) => {
fn(`child process exited with code ${code}`, 'end');
});
}
下面是express所欲執行的shell...
# File: /tmp/test.sh
echo 1
sleep 1
echo 2
sleep 2
echo 3
sleep 3
啟動Server後,再透過curl測試...
curl localhost:3000/exec
stdout: 1
stdout: 2
stdout: 3
child process exited with code 0
done...
將會發現,上面的執行結果將是一行一行回覆回來,在結束之前connection將不會中斷...
細看執行重點
上面的程式之所以可以block住connection並且一段一段回傳結果,其中重點在express routing中使用res.write()來做data的回傳,另外也因為child_process.spawn()提供event driven的方式,在每筆data回傳時候呼叫對應的event執行方式...