Skip to content

Commit

Permalink
quiz: review event loop questions
Browse files Browse the repository at this point in the history
  • Loading branch information
yangshun committed Jun 9, 2024
1 parent 8417e54 commit 4cb2ceb
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 319 deletions.
Binary file removed assets/javascript-runtime.png
Binary file not shown.
131 changes: 0 additions & 131 deletions packages/quiz/questions/what-are-microtasks-and-macrotasks/en-US.mdx

This file was deleted.

This file was deleted.

113 changes: 52 additions & 61 deletions packages/quiz/questions/what-are-server-sent-events/en-US.mdx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
---
title: What are server sent events ?
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:
[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 are used with `EventSource` instances that opens a connection with a server and allows client to receive events from the server. Connections created by server-sent events are persistent (similar to the `WebSocket`s), however there are a few 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 |
| Property | `WebSocket` | `EventSource` |
| --- | --- | --- |
| Direction | Bi-directionalboth client and server can exchange messages | Unidirectional – only server sends data |
| Data type | Binary and text data | Only text |
| Protocol | WebSocket protocol (`ws://`) | Regular HTTP (`http://`) |

**Creating an EventSource**
**Creating an event source**

```js
const eventSource = new EventSource('/sse-stream');
Expand All @@ -26,7 +26,7 @@ eventSource.addEventListener('open', () => {
console.log('Connection opened');
});

// Fired when a message is received from the server
// Fired when a message is received from the server.
eventSource.addEventListener('message', (event) => {
console.log('Received message:', event.data);
});
Expand All @@ -44,12 +44,12 @@ const express = require('express');
const app = express();

app.get('/sse-stream', (req, res) => {
// `Content-Type` need to be set to `text/event-stream`
// `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
// Each message should be prefixed with data.
const sendEvent = (data) => res.write(`data: ${data}\n\n`);

sendEvent('Hello from server');
Expand All @@ -69,59 +69,63 @@ In this example, the server sends a "Hello from server" message initially, and t

---

## `Server-sent events`
## Server-sent events (SSE)

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.
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:
## 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');
```
```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!
```js
event: message
data: Hello, world!

event: update
id: 123
data: {"temperature": 25, "humidity": 60}
```
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:
4. On the client-side, the `EventSource` object receives these events and dispatches them as browser events, which can be handled using event listeners or the `onmessage` event handler:

```js
eventSource.onmessage = function (event) {
console.log('Received message:', event.data);
};
```js
eventSource.onmessage = function (event) {
console.log('Received message:', event.data);
};

eventSource.addEventListener('update', function (event) {
console.log('Received update:', JSON.parse(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`
## SSE features

- **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.
- **Unidirectional**: Only the server can send data to the client. For bidirectional communication, web sockets would be more appropriate.
- **Retry mechanism**: The client will retry the connection if it fails, with the retry interval specified by the `retry:` field from the server.
- **Text-only data**: SSE can only transmit text data, which means binary data needs to be encoded (e.g., Base64) before transmission. This can lead to increased overhead and inefficiency for applications that need to transmit large binary payloads.
- **Built-in browser support**: Supported by most modern browsers without additional libraries.
- **Event types**: SSE supports custom event types using the `event:` field, allowing categorization of messages.
- **`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. However, there is no built-in mechanism to replay missed events during the disconnection period. You may need to implement a mechanism to handle missed events, such as using the `Last-Event-Id` header.
- **Connection limitations**: Browsers have a limit on the maximum number of concurrent SSE connections, typically around 6 per domain. This can be a bottleneck if you need to establish multiple SSE connections from the same client. Using HTTP/2 will mitigate this issue.

### Disadvantages of SSE
## Implementing SSE in JavaScript

- **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.
The following code demonstrates a minimal implementation of SSE on the client and the server:

### Implementing `SSE` in JavaScript
- 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.

#### Client-Side Code:
On the client:

```js
// Create a new EventSource object
Expand All @@ -143,7 +147,7 @@ eventSource.onopen = function () {
};
```

#### Server-Side Code:
On the server:

```js
const http = require('http');
Expand All @@ -160,7 +164,7 @@ http

// Function to send a message
const sendMessage = (message) => {
res.write(`data: ${message}\n\n`);
res.write(`data: ${message}\n\n`); // Messages are delimited with double line breaks.
};

// Send a message every 5 seconds
Expand All @@ -183,26 +187,13 @@ http
});
```

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.
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)
- [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/)
Loading

0 comments on commit 4cb2ceb

Please sign in to comment.