DEV Community

Play Button Pause Button
Manish Pillai
Manish Pillai

Posted on

SSE - Server Sent Event

If you’ve ever wanted your server to push live updates to a browser without the client constantly polling, Server-Sent Events (SSE) are a simple and efficient solution. In this post, we’ll explore what SSE is, how to implement it in Golang, and why the client side requires EventSource.

I’ve also made a short video demo to show it in action, which you can check out below.


What is SSE?

SSE is a standard that allows a server to send continuous updates over a single HTTP connection to the client. Unlike WebSockets, SSE is unidirectional—the server sends data, but the client cannot push messages back on the same connection.

Common use cases:

  • Live dashboards and monitoring systems.
  • Chat notifications or social feed updates.
  • Real-time logs or stock price tickers.

Creating an SSE Server in Go

Here’s how to implement a basic SSE server using Go:

package main

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

    "github.com/gorilla/mux"
)

func main() {
    router := mux.NewRouter()
    server := http.Server{
        Addr:    ":8080",
        Handler: router,
    }

    router.HandleFunc("/sse", handleEvents).Methods("GET")

    fmt.Println("SSE server running on :8080")
    err := server.ListenAndServe()
    if err != nil {
        panic(err)
    }
}

func handleEvents(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Content-Type", "text/event-stream")
    w.Header().Set("Cache-Control", "no-cache")
    w.Header().Set("Connection", "keep-alive")

    ticker := time.NewTicker(2 * time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-ticker.C:
            fmt.Fprintf(w, "data: %s\n\n", time.Now().String())
            if f, ok := w.(http.Flusher); ok { f.Flush() }
        case <-r.Context().Done():
            return
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Key points:

  • Content-Type: text/event-stream is mandatory.
  • Each message must start with data: and end with a double newline \n\n.
  • Use http.Flusher to push data immediately without buffering.

The Client Side – EventSource

SSE is designed for browsers, which support a built-in EventSource API. This makes it very simple to receive server events:

<script>
const es = new EventSource("http://localhost:8080/sse");

es.onopen = () => console.log("SSE connected");
es.onmessage = e => console.log("message:", e.data);
es.onerror = e => console.error("SSE error", e);
</script>
Enter fullscreen mode Exit fullscreen mode
  • EventSource automatically reconnects if the connection drops.
  • It parses data: messages sent by the server.
  • This is why the client usually needs a browser or JS runtime that supports EventSource.

SSE vs Sockets

While SSE is perfect for server → client streaming, for bidirectional communication where the client also sends messages to the server in real time, WebSockets are more suitable.

SSE:

  • Unidirectional (server → client)
  • Works over HTTP/HTTPS
  • Simpler to implement

WebSockets:

  • Bidirectional
  • More complex but flexible
  • Great for chat apps, multiplayer games, and live collaboration tools

Quick Note on Streaming HTTP

SSE is a type of streaming HTTP, where the server sends data in chunks without closing the connection. Streaming HTTP itself is not limited to browsers and can be used in server-to-server communication as well.


Check Out the Video Demo

I’ve created a short video demonstrating how to implement SSE in Go, including the server code and how EventSource handles the data in a browser.


Conclusion:
SSE is a lightweight and efficient way to push live updates from servers to browsers. It’s simpler than WebSockets when you only need server-to-client communication, making it ideal for dashboards, logs, and notifications.

Top comments (2)

Collapse
 
gkoos profile image
Gabor Koos

Clear and concise introduction to SSE! Consider adding a mention of reconnection logic and how to handle lost connections.

Collapse
 
pillaimanish profile image
Manish Pillai

Thanks for the suggestion @gkoos. I will try to add that. Thanks again :)