A simple guide to Server Sent Events (SSE) and EventSource

Omer Keskinkilic
Pon.Tech.Talk
Published in
5 min readApr 26, 2024
A simple demonstration of the SSE

Real-time data delivery has become an essential requirement for many web applications. Whether it’s a live news update, real-time stock prices, or a chat application, the need to push data from the server to the client in real time has never been more prevalent.

What are Server Sent Events (SSE)?

Server Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via an HTTP connection(1). Unlike WebSockets, which is a two-way communication channel, SSE is a one-way channel from the server to the client, making it a perfect choice for applications that only require server-to-client updates.(2) (3)

Using EventSource to Handle SSE

EventSource is an API provided by modern browsers for receiving SSE. It establishes a persistent connection between the client and the server, allowing the server to send updates whenever necessary. With the EventSource api, we can handle the stream chunks (4) easily. The methods of EventSource are simply adoptable. Before proceeding with examples, I suggest you to read the API documentation on these sources. (5) (6)

Practical Implementation: Creating a Server and Client

We will create our server and client implementations. They will be basic examples in JavaScript, however you can easily implement to any language you prefer, or any JavaScript library / framework.

Let’s first create a folder called sse which will contain backend and frontend. At the end of this article, folder tree will look like this:

.
└── sse/
├── backend/
│ ├── server.js
│ ├── package.json
│ ├── package-lock.json
│ └── node_modules
└── frontend/
├── index.html
└── client.js

node and npm must be available in your system for this example.

1. Backend

Inside of sse folder, create a folder named backend, and inside of it, create server.js file. We will create a Node.js server-side application using the Express.js framework. First execute following commands inside of backend directory.

npm init -y
npm i express cors

Create a file named server.js and copy/paste below code snippet in it.

server.js

I will not go into all the details in the code, but let’s focus on the route handler :

  1. It sets the response headers Content-Type to text/event-streamand Cache-Controlto no-store. This indicates that the server will be sending a Server-Sent Event (SSE) stream and that the response should not be cached. If response’s Content-Type is nottext/event-stream , then fail the connection. (7–Article 15/3)
  2. It then initialises a counter to 5 and sets up an interval that fires every 1 second.
  3. In each interval, it checks if the counter is greater than 0. If it is, it writes a new event named CustomEvent (it can be any string) to the SSE stream with the current time. If the counter is not greater than 0, it sends a closing event named Close (it can be any string too) and ends the interval.

2. Frontend

Create the frontend folder inside of sse . Then create index.html which will have the basic markup and a ul element, and client.js file which is designed to work with the server-side code above. Below you will find both file codes:

index.html
client.js

EventSource Instance

In client.js we first create the connection with new EventSource(...) method, then we attach some events to listen. For details of the event handling, please have a look at this resource. (8)

  1. source.addEventListener("CustomEvent", (event) => {...}); - This line adds an event listener for the "CustomEvent" event. When a "CustomEvent" event is received, it parses the event data from JSON to a JavaScript object, extracts the "time" property, and passes it to appendToList(), which appends it to the ul in the document.
  2. source.addEventListener("Close", (event) => {...}); - This line adds an event listener for the "Close" event. When a "Close" event is received, it passes the event data to appendToList() and closes the EventSource connection.
  3. source.onerror = (error) => {...}; - This line sets an error handler for the EventSource. If an error occurs, it logs the error message to the console. You can create you own error handling logic.

After running backend and frontend folders locally, here is what we will see on the page:

EventStream tab in dev tools

As you see, each second we get a chunk of data, then we close the stream. In the dev tools, we can also see the chunks in EventStream tab with the event names. How cool it is!

If you use an implementation of EventSource and not using native EventSource, you might see the tab stays empty. It is a known issue.(9) . There are some browser extensions to use the EventStream tab in those implementations which we will cover in the follow up article. (e.g. SSE viewer Chrome extension (10) .

Summarise

In this article, we’ve explored the concept of Server Sent Events (SSE) and how to use EventSource to handle these events. We’ve seen how SSE, a server push technology, can establish a one-way communication channel from the server to the client, making it ideal for real-time data delivery in applications that only require server-to-client updates.

We’ve also delved into a practical implementation, creating a server and client using JavaScript. This hands-on approach not only helps us understand the theoretical aspects but also equips us with the practical skills needed to implement these concepts in real-world applications.

In the upcoming article, we will create another app with SSE, but this time it will support a request rather then GET , since native EventSource only accept GET request.

Github Repo => https://github.com/omer-pon/sse-eventsource

Resources

  1. https://en.wikipedia.org/wiki/Server-sent_events#:~:text=Server-Sent%20Events%20(SSE),client%20connection%20has%20been%20established.
  2. https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
  3. https://developer.mozilla.org/en-US/docs/Web/API/EventSource
  4. https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams
  5. Same as 3
  6. https://html.spec.whatwg.org/multipage/server-sent-events.html#the-eventsource-interface
  7. Same as 7
  8. https://developer.mozilla.org/en-US/docs/Web/API/EventSource/message_event
  9. https://github.com/Azure/fetch-event-source/issues/3#issue-788078889
  10. https://chromewebstore.google.com/detail/sse-viewer/pkofiecpdokojdgoccnbfplkphbmppaf (Date of access: 23.04.2024)

--

--