Sunday, May 10, 2020

Tip: How to use HTML5 Server Side Events

Server Side Events (SSE) allows the web server (node.js, IIS, Apache, etc) to keep a connection active with the client browser while server is pushing data to the client whenever needed. However SSE is not the same as WebSockets as it can only push data from server whereas WebSockets can both receive and push data. Below is a very simple SSE application developed using node.js and HTML.


Server Code

const express = require('express');
const app = express();
app.use(express.static('public'));
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:10001');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.get('/countdown', function (req, res) {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
console.log("Connected to server");
countdown(res, 10)
});
function countdown(res, count) {
console.log("count down " + count);
res.write("data:" + count + "\n\n"); // this need to be set in the right format in order for the "message" event to trigger at the client.
if (count)
setTimeout(() => countdown(res, count - 1), 1000)
else
res.end()
}
app.listen(3000, () => console.log('SSE app listening on port 3000!'))
view raw server.js hosted with ❤ by GitHub


Client Code

You can include the following snippet in the html header section
<script>
if (!!window.EventSource) {
var source = new EventSource('http://localhost:3000/countdown')
source.addEventListener('message', function (e) {
document.getElementById('data').innerHTML = e.data;
});
source.addEventListener('open', function (e) {
document.getElementById('state').innerHTML = "Connected"
}, false);
source.addEventListener('error', function (e) {
const id_state = document.getElementById('state')
if (e.eventPhase == EventSource.CLOSED)
source.close()
if (e.target.readyState == EventSource.CLOSED) {
id_state.innerHTML = "Disconnected"
}
else if (e.target.readyState == EventSource.CONNECTING) {
id_state.innerHTML = "Connecting..."
}
}, false)
} else {
console.log("Your browser doesn't support SSE")
}
</script>
view raw client.html hosted with ❤ by GitHub

You will receive the following in Chrome debugger if the message is sent successfully from the server.