Server-Sent Events (SSE)
Server-Sent Events (SSE) allows a web server to push real-time updates to a client (i.e. a web browser) over a single, long-lived HTTP connection.
Unlike bidirectional WebSockets, SSE is unidirectional, meaning communication only flows from the server to the client.
Example using Go
package main
import "fmt"; import "log"; import "net/http"; import "time";
func sseHandler(w http.ResponseWriter, r *http.Request) {
// sse headers
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
// ticker to send events every second
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
done := r.Context().Done() // channel to signal when client disconnects
for {
select {
case <-ticker.C: // clock
// send current time as an event
currentTime := time.Now().Format(time.RFC3339)
fmt.Fprintf(w, "data: %s\n\n", currentTime)
// flush response writer to send data immediately
if f, ok := w.(http.Flusher); ok {
f.Flush()
} else {
log.Println("Streaming unsupported!")
return
}
case <-done:
log.Println("Client disconnected")
return
}
}
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
})
http.HandleFunc("/events", sseHandler)
log.Println("SSE server listening on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
<!DOCTYPE html> <html> <head> <title>SSE Example</title> </head> <body> <h1>SSE Example</h1> <div id="output"></div> <script> const outputDiv = document.getElementById('output'); const eventSource = new EventSource('/events'); // establish SSE connection eventSource.onmessage = (event) => { outputDiv.innerHTML += `<p>Received: ${event.data}</p>`; }; eventSource.onerror = (error) => { console.error("SSE error:", error); eventSource.close(); // Close the connection on error }; eventSource.onopen = () => { console.log("SSE connection opened"); } </script> </body> </html>