Handling ServerSent event in React App

Photo by Lars Kienle on Unsplash

Handling ServerSent event in React App

Hello Guys, welcome back to my blog. Today we will be creating our small server and React app to learn about Server-Sent Events and how to handle them in a React App.

But before we even start building anything let's learn about Server-Side Events (SSE)

Server-Side Event

A Server-Sent Event (SSE) is a simple and efficient mechanism for sending real-time updates from the server to the client over HTTP. It is a standard web technology that enables servers to push data to web clients over a single, long-lived HTTP connection in real time.

In simple words, you can send push events from the backend to the frontend. Below is a small explanation to understand it better.

Server-sent event android client - YouTube

Here's a basic overview of how Server-Sent Events work:

  1. Connection Establishment: The client initiates a request to the server, and the server responds with a special media type called text/event-stream. This indicates that the server will be sending events in a specific format.

     HTTP/1.1 200 OK
     Content-Type: text/event-stream
     Cache-Control: no-cache
     Connection: keep-alive
    
  2. Event Format: The server sends events to the client in a specific text-based format. Each event is a plain text message with a series of fields, such as "event," "data," and "id." For example:

     plaintextCopy codeevent: eventName
     data: This is the event data
     id: 123
    
  3. Handling Events on the Client: The client receives these events and can handle them using JavaScript. The EventSource API is commonly used for this purpose. The client can define event listeners to process specific types of events.

     const eventSource = new EventSource('/events');
    
     eventSource.onmessage = function(event) {
       console.log(event.data);
     };
    
     eventSource.onerror = function(error) {
       console.error('EventSource failed:', error);
     };
    
  4. Connection Persistence: The SSE connection remains open, allowing the server to push new events to the client whenever necessary. This is different from traditional request-response mechanisms where the client initiates each request.

Creating a simple Golang App

I will keep the implementation simple here. In this section, we just create a simple Server Sent Event in Golang. Which listens to /stream route.

package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    fmt.Printf("starting server on 8000\n")
    http.HandleFunc("/stream", func(w http.ResponseWriter, r *http.Request) {
        // Set headers
        w.Header().Set("Content-Type", "text/event-stream")
        w.Header().Set("Cache-Control", "no-cache")
        w.Header().Set("Connection", "Keep-alive")

        // Send an Intial Connection Response

        fmt.Fprint(w, "data: Connection")
        flusher, ok := w.(http.Flusher)
        if !ok {
            http.Error(w, "Streaming not supported", http.StatusInternalServerError)
            return
        }

        // Simulates sending event every second

        for {
            fmt.Fprintf(w, "data: %s\n\n", time.Now().Format("15:04:05"))
            flusher.Flush()
            time.Sleep(1 * time.Second)
        }

    })
    err := http.ListenAndServe(":8000", nil)
    if err != nil {
        log.Fatal(err)
    }

}

This is it for the development of the server. Let's look at the React app in the next section.

Creating a React app

In this section we will create a React app, For this tutorial we will be using Remix. Remix is a framework built for React.

npx create-remix

Once that is done, just add a useEffect with the below code.

useEffect(() => {
    const eventSource = new EventSource('http://localhost:8000/stream');

    eventSource.onmessage = (event) => {
      setSSEData(event.data);
    };

    eventSource.onerror = (error) => {
      console.error('EventSource failed:', error);
      eventSource.close();
    };

    return () => {
      // Clean up the event source when the component is unmounted
      eventSource.close();
    };
  }, []); // Empty dependency array ensures the effect runs only once

Let me explain what is happening above, Once we create a new EventSource on the route we are streaming the data and storing it into eventSource. then we listen to onMessage and set the setSSEData to the new data we get from the event.

Now, it's up to you, what you want to do with this data now. What I did was simply display the data like below.

TL;DR:

This tutorial covers Server-Sent Events (SSE) with a Golang server and a React app using Remix. SSE allows real-time updates from the server to the client over HTTP. The Golang server listens to the /stream route, sending periodic events. The React app, created with Remix, uses EventSource to receive and display the streaming data. The server's SSE implementation and React's useEffect for handling events is explained step by step.

Did you find this article valuable?

Support Ashish maurya by becoming a sponsor. Any amount is appreciated!