Server Sent Events
LIVE UPDATES WITH
JavaScript community
Agenda
- Server Sent Events standard
- How it works
- Compare with WebSocket / Long Polling
- Browser Support
- Use cases
- EventSource API
- Example using Node.js (Express) and Vue.js
Wait, Vue ?
Why Vue ?
46 % developers want to learn it, but didn't try
Server Sent Events standard
Server-Sent Events (SSE) is a server push technology enabling a browser to receive automatic updates from a server via HTTP/2 (HTTP/1.1) connection.
Server Sent Events
Is this a WebSocket ?
How it works
The server receives a regular HTTP request from the client.
Every time that the server writes an event to the HTTP response, the client will receive it and process it in a listener callback function
The client creates a new JavaScript EventSource object, passing it the URL of an endpoint which is expected to return a stream of events over time.
1
2
3
Benefits of HTTP/2
- HTTP/2 is backwards compatible with HTTP/1
- Multiplexing — Multiple Requests per Connection
- Prioritization — Loading Essential Resources First
- HPACK Compression — Reducing Junk in Headers
Compare with other Approaches
WebSocket
WebSocket
- No reconnection by default
- Custom authentication logic
- Scaling problems
- More app complexity
SSE
- Reconnection out of the box
- HTTP authentication
- No scaling problems
- Easy to use
Except one thing...
SSE is unidirectional. When you open a SSE connection, only the server can send data to the client (browser, etc.). The client cannot send any data.
Solution: HTTP requests + EventSource
“I don’t care about your “Server-Sent stuff”, I will request every half a second!”
HTTP Polling
SSE
- Simpler implementation and Data efficiency
- It is automatically multiplexed over HTTP/2 out of the box
- Limits the number of connections for data on the client to one
- SSE provides a memory-efficient implementation of XHR streaming. Unlike a raw XHR connection, which buffers the full received response until the connection is dropped, an SSE connection can discard processed messages without accumulating all of them in memory.
- Polling responses can’t really be in sync
- Polling requiring 3 round-trips (TCP SIN, SSL, and Data)
- Timeouts (Connection getting closed by the proxy server if it remains idle for too long)
Browser Support
Can I Use ...
Make it work on IE & Edge !
Use Cases
A few simple examples of applications that could make use of Server-Sent Events:
- A real-time chart of streaming stock prices
- Real-time news coverage of an important event (posting links, tweets, and images)
- A live Github / Twitter dashboard wall fed by Twitter’s streaming API
- A monitor for server statistics like uptime, health, and running processes.
EventSource API
The EventSource interface
To enable servers to push data to Web pages over HTTP or using dedicated server-push protocols, this specification introduces the EventSource interface.
created() {
const receiveMessage = this.receiveMessage;
const eventSource = new EventSource("http://localhost:3000/event-stream");
eventSource.onmessage = function(event) {
console.log("New message", event.data);
receiveMessage(JSON.parse(event.data));
};
}
Client-side implementation
Note: event.data is a string, so we need to parse it and convert to object
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.get('*', (req, res) => res.send('OK'));
app.get('/sse', (req, res) => {
// create SSE connection
});
app.listen(3000, () => console.log('server started...'));
Server-side implementation
app.get('/sse', (req, res) => {
// SSE Setup
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
res.write('\n');
let messageId = 0;
const intervalId = setInterval(() => {
res.write(`id: ${messageId}\n`);
res.write(`data: Test Message -- ${Date.now()}\n\n`);
messageId += 1;
}, 1000);
req.on('close', () => {
clearInterval(intervalId);
});
});
SSE Controller
function createConnections() {
let list = [];
return {
send(message) {
messageId++;
list.forEach(({ id, req, res }) => {
console.log('Sending for: ', id)
res.write(`id: ${messageId}\n`);
res.write(`data: ${JSON.stringify(message)}\n\n`);
});
},
add(id, req, res) {
list.push({ id, req, res })
},
remove(id) {
list = list.filter(item => item.id !== id);
}
}
}
How to manage connections ?
Or you can use events.js
Live Coding
Thank you!
Link to slides:
Live Updates with Server Sent Events
By Vladimir Vyshko
Live Updates with Server Sent Events
- 525