In web application space, there are a few strategies that can be used to retrieve real-time data from the server. Some of the most popular ones are:
- Continuous polling.
- Web sockets.
- Server Sent Events (SSE).
- Managed Cloud services like PubNub, Firebase realtime database/function etc.
- Push notification services like OneSignal, Firebase push notifications etc.
In this post, we will explore the basics of Server Sent Events. I will use Go to write the server logic, but SSE support is available in all other programming languages and frameworks.
All the code referenced in this blog post can be found here. Interested users can clone the repository and follow the instructions in readme.md. If you find any mistakes or have any questions or queries, please create an issue here and I will be more than happy to clarify them.
Server sent events (SSE)⌗
From Mozilla website:
Traditionally, a web page has to send a request to the server to receive new data; that is, the page requests data from the server. With server-sent events, it’s possible for a server to send new data to a web page at any time, by pushing messages to the web page. These incoming messages can be treated as Events + data inside the web page.
SSE is a powerful tool to retrieve real-time updates with low latency over a single persistent HTTP connection. This protocol is widely supported by all browsers and is integrated with the HTML standard. What makes SSE truly stand out is its unique ability to allow the server to take the lead and push data to the client, rather than waiting for the client to initiate a request. This approach eliminates the need for clients to constantly poll the server, resulting in reduced network traffic and increased efficiency.
It is important to note that SSE are one way message transmission technology. The data flow happens from Server to the client. Client requests events by triggering an http endpoint over http, the server then performs the backend logic and returns the data as and when it is available. When the server has sent all the data, the connection is closed.
To demonstrate the SSE mechanism, we will create a dummy application that gets the list of random cat breeds from server and dynamically displays them on the browser. For simplicity of implementation, we will use Go to serve both backend logic as well as the html. Additionally, all the error handling is skipped to keep the demonstration simple and easy to understand.
First we create our server component. In the setup below, we first wire the html file present in the static dir to serve the frontend on the root path
/. On path
/events, we write the logic to generate the server sent events.
- Bind the content under
staticdirectory on the server to serve its contents on root path
- Serve the logic to return server-sent-events on
- On the
eventsHandler(), set the correct response headers.
- For each loop iteration, append server event to the response output stream.
- Flush each event back to the client.
- After 10 iterations, break the loop. This will cause the connection to drop. The client can detect the connection drop and perform any cleanups if required.
The client component, on click of the button calls the function
fetchData(), which initiates an
EventSource request. It appends the server-sent data to the table as long as the connection is alive. On drop of the connection, the
onerror() function is triggered where the
eventsource is closed and cleanup can be done, if required.
- Initiate request to server to send events in response
- As long as events are available, transform the data and append it to the table.
- Capture error, when the connection is dropped by server and close the event source.
Here is a demo of the application. If you clone the repository, go to localhost:8080, you would be greeted with the landing page. On click of the button, the server will start streaming the cat breeds and the UI will be updated with cat breeds in realtime.
SSE is a great toolkit for the use cases where unidirectional data flow is required from server to client at low latency. It is a useful approach for handling situations like social media notifications, news feeds, or delivering data into a client-side storage, live graphs or progress updates. It is a good alternative to trivial techniques like client side polling using ajax and can use multiple data formats like json, xml or html fragments.