Some tasks require subsequent requests from a server so that the user sees the most up-to-date UI. However, no feedback from the client is needed. Also, we only need to transfer text data. For example, these are news feeds, message alerts, or exchange rate charts. Since we don't want to send any feedback from the client, using WebSockets may be redundant. In these cases, server-sent events (SSE) are considered good practice. This topic will focus on understanding, sending, and receiving SSE.
Server-sent connection
Server-sent events (SSE) is a technology that allows to establish continuous transfer of messages from the server to the client. They are unidirectional, meaning they can only be sent from the server to the client. In other cases like sending data other than text or sending feedback from the client, we can't use server-sent events.
SSEs are based on EventSource API. It is a client-side JavaScript API that allows web developers to receive server-sent events from the server over a persistent HTTP connection.
Server-sent connections are controlled by EventSource objects. EventSource object invokes an SSE connection as soon as it's created.
const eventSource = new EventSource("your-url");
Just like WebSockets, SSE need an established connection with the server. However, unlike WebSockets, SSE use an HTTP protocol to connect. The URL may look any way you want as long as it provides a connection to the server.
withCredentials property
withCredentials parameter indicates whether or not credentials will be included when the connection is established. This allows the server to authenticate the request with cookies and headers and provide access to protected resources.
const eventSource = new EventSource("your-url", {
withCredentials: true,
});readyState property
Just like a WebSockets connection, SSE has the readyState property, which has the following values:
- 0 — "CONNECTING" means the connection is not yet established
- 1 — "OPEN" is for data exchange
- 2 — "CLOSED" means the connection is already closed.
if(eventSource.readyState === 0) {
console.log('Connecting...');
}Data transfer with SSE
There're several events associated with SSE.
When the connection is open, it fires the onopen event:
eventSource.onopen = (e) => {
console.log("The connection has been established.");
};
When data from the server is received, we can extract it using the onmessage event listener:
eventSource.onmessage = (e) => {
console.log("Message", message.data); // Message some text
};
A message received from the server is an object of a MessageEvent type. It contains a lot of metadata concerning the connection and message, and the message data itself. Most of the time, we are interested in message.data, but sometimes a message provides other useful information:
type— event type, such as "message", "error", or "open".retry— recommended retry time in milliseconds. It can't be set from the client side.lastEventId— the ID of the last event received by the client.
The format used to send the message is called text/event-stream and the format is data: exemple text. Because of this format type, SSE is only limited to sending simple text data.
Closing the connection
SSE connection can also be closed:
eventSource.close();
A message received is an Object of the MessageEvent type, but most of the time we are interested inmessage.data.
Received data can, of course, be processed and printed on a page.
Error handling
General error handling is provided by the onerror method:
eventSource.onerror = (error) => {
console.log("Error", error.data);
};
Although most browsers support SSE, it's not supported by all. If there is a possibility that a user didn't update their browser since 2015, it's better to provide additional error handling.
if (typeof EventSource !== "undefined") {
// continue with the program and establish a connection
} else {
alert("Sorry, your browser does not support server-sent events");
}Conclusion
Using SSE is a simple and efficient way to implement real-time web communication. It is a lightweight protocol that supports HTTP and can be used for various cases, for example, to provide notifications to the user, or to set stock market prices in real-time. SSE are unidirectional, so they can only be used in cases when the client doesn't need to interact with the server. However, it can only transfer text data.