quiz/js: server-sent events in javascript (#469)

This commit is contained in:
Vikas yadav 2024-06-06 10:07:21 +05:30 committed by GitHub
parent 81efc55a72
commit b6cedbf3ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 219 additions and 0 deletions

View File

@ -0,0 +1,208 @@
---
title: What are server sent events ?
---
## TL;DR
[`Server-sent events (SSE)`](https://html.spec.whatwg.org/multipage/comms.html#the-eventsource-interface) is a standard that allows a web page to receive automatic updates from a server via an HTTP connection. `Server-sent events` describe a built-in-class `EventSource` that keeps connection with the server and allows client to receive events from server. Connection created by `Server-sent events` are persistent similar to the `WebSocket`, however there are several differences:
| WebSocket | EventSource |
| --- | --- |
| Bi-directional: both client and server can exchange messages | One-directional: only server sends data |
| Binary and text data | Only text |
| WebSocket protocol | Regular HTTP |
**Creating an EventSource**
```js
const eventSource = new EventSource('/sse-stream');
```
**Listening for events**
```js
// Fired when the connection is established.
eventSource.addEventListener('open', () => {
console.log('Connection opened');
});
// Fired when a message is received from the server
eventSource.addEventListener('message', (event) => {
console.log('Received message:', event.data);
});
// Fired when an error occurs.
eventSource.addEventListener('error', (error) => {
console.error('Error occurred:', error);
});
```
**Sending events from server**
```js
const express = require('express');
const app = express();
app.get('/sse-stream', (req, res) => {
// `Content-Type` need to be set to `text/event-stream`
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
// Each message should be prefixed with data
const sendEvent = (data) => res.write(`data: ${data}\n\n`);
sendEvent('Hello from server');
const intervalId = setInterval(() => sendEvent(new Date().toString()), 1000);
res.on('close', () => {
console.log('Client closed connection');
clearInterval(intervalId);
});
});
app.listen(3000, () => console.log('Server started on port 3000'));
```
In this example, the server sends a "Hello from server" message initially, and then sends the current date every second. The connection is kept alive until the client closes it
---
## `Server-sent events`
Server-Sent Events (SSE) is a standard that allows a server to push updates to a web client over a single, long-lived HTTP connection. It enables real-time updates without the client having to constantly poll the server for new data.
### How `SSE` works:
1. The client creates a new `EventSource` object, passing the URL of the `server-side` script that will generate the event stream:
```js
const eventSource = new EventSource('/event-stream');
```
2. The server-side script sets the appropriate headers to indicate that it will be sending an event stream (`Content-Type: text/event-stream`), and then starts sending events to the client.
3. Each event sent by the server follows a specific format, with fields like `event`, `data`, and `id`. For example:
```js
event: message
data: Hello, world!
event: update
id: 123
data: {"temperature": 25, "humidity": 60}
```
4. On the client-side, the `EventSource` object receives these events and dispatches them as `DOM` events, which can be handled using event listeners or the `onmessage` event handler:
```js
eventSource.onmessage = function (event) {
console.log('Received message:', event.data);
};
eventSource.addEventListener('update', function (event) {
console.log('Received update:', JSON.parse(event.data));
});
```
5. The `EventSource` object automatically handles reconnection if the connection is lost, and it can resume the event stream from the last received event ID using the `Last-Event-ID HTTP header`.
### Advantages of `SSE`
- **Simpler than WebSockets**: Easier to implement and understand than `WebSockets` for many use cases.
- **Automatic Reconnection**: The client handles reconnections automatically.
- **Lightweight**: Uses simple text-based messages and a single `HTTP` connection.
- **Built-in Browser Support**: Supported by most modern browsers without additional libraries.
### Disadvantages of SSE
- **Unidirectional**: Only the server can send data to the client. For bidirectional communication, WebSockets would be more appropriate.
- **Connection Limitations**: Limited to the maximum number of open `HTTP` connections per browser, which can be an issue with many clients.
### Implementing `SSE` in JavaScript
#### Client-Side Code:
```js
// Create a new EventSource object
const eventSource = new EventSource('/sse');
// Event listener for receiving messages
eventSource.onmessage = function (event) {
console.log('New message:', event.data);
};
// Event listener for errors
eventSource.onerror = function (error) {
console.error('Error occurred:', error);
};
// Optional: Event listener for open connection
eventSource.onopen = function () {
console.log('Connection opened');
};
```
#### Server-Side Code:
```js
const http = require('http');
http
.createServer((req, res) => {
if (req.url === '/sse') {
// Set headers for SSE
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
});
// Function to send a message
const sendMessage = (message) => {
res.write(`data: ${message}\n\n`);
};
// Send a message every 5 seconds
const intervalId = setInterval(() => {
sendMessage(`Current time: ${new Date().toLocaleTimeString()}`);
}, 5000);
// Handle client disconnect
req.on('close', () => {
clearInterval(intervalId);
res.end();
});
} else {
res.writeHead(404);
res.end();
}
})
.listen(8080, () => {
console.log('SSE server running on port 8080');
});
```
In this example:
- The server sets the appropriate headers to establish an `SSE` connection.
- Messages are sent to the client every 5 seconds.
- The server cleans up the interval and ends the response when the client disconnects.
### Considerations
- **Event Types**: `SSE` supports custom event types using the `event:` field, allowing you to categorize messages.
- **Retry Mechanism**: The client will retry the connection if it fails, with the retry interval specified by the `retry:` field from the server.
- **Last-Event-ID**: The client sends the `Last-Event-ID` header when reconnecting, allowing the server to resume the stream from the last received event.
- **CORS and Authentication**: Ensure `CORS` headers are correctly configured for cross-origin requests, and consider secure methods for authentication and authorization.
## Summary
`Server-sent Events` provide an efficient and straightforward way to push updates from a server to a client in real-time. They are particularly well-suited for applications that require continuous data streams but do not need full `bidirectional` communication. With built-in support in modern browsers, `SSE` is a reliable choice for many real-time web applications.
## Further reading
- [Using server-sent events - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
- [Server sent events - javascript.info](https://javascript.info/server-sent-events)
- [Server-Sent Events: A webSockets alternative ready for another look](https://ably.com/topic/server-sent-events)
- [What are SSE (Server-Sent Events) and how do they work?](https://bunny.net/academy/http/what-is-sse-server-sent-events-and-how-do-they-work/)

View File

@ -0,0 +1,11 @@
{
"slug": "what-are-server-sent-events",
"languages": [],
"companies": [],
"premium": false,
"duration": 5,
"published": true,
"topics": ["javascript"],
"importance": "mid",
"difficulty": "hard"
}