On the client
you only need to create an EventSource and attach a callback to get data everytime the server pushes
<!doctype html>
<html>
<head>
<title>Exemple</title>
</head>
<body>
<p>Open console</p>
</body>
<script>
var source = new EventSource('/stream');
source.addEventListener('message', function(event) {
console.log(event.data);
}, false);
</script>
</html>
On the server
you need to use the special header "text/event-stream" and write your data prefixed with "data: ".
The client will get data immediately
const express = require('express')
const app = express()
app.get('/', function (req, res) {
res.sendFile(__dirname+'/index.html');
})
app.get('/stream', function (req, res) {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
});
var i = setInterval(() => res.write('data: ' + (new Date().toISOString()) +'\n\n'), 1000);
setTimeout(() => {
clearInterval(i);
res.end();
}, 5000)
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
app can also emit and receive event so that streaming a long command can work even if you reload the page.
const express = require('express')
const app = express()
app.get('/', function (req, res) {
res.sendFile(__dirname+'/index.html');
})
app.get('/eventlisteners', function (req, res) {
res.send(''+app.rawListeners('event').length);
console.log(app.rawListeners('event'));
})
app.get('/stream', function (req, res) {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
});
var handler = (data) => {
res.write('data: ' + data + '\n\n')
}
app.on('event', handler);
res.on('close', () => {
app.removeListener('event', handler)
})
})
app.get('/convert', function (req, res) {
var i = setInterval(() =>
app.emit('event', (new Date().toISOString()))
, 1000);
setTimeout(() => {
clearInterval(i);
}, 5000)
res.send('ok');
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})