go 31 lines · 7 steps

Streaming server-sent events in Gin

A Gin handler pushes a metrics snapshot to the browser every second over an SSE connection until the client disconnects.

Explained by highlit
1func StreamMetrics(c *gin.Context) {
2 clientGone := c.Request.Context().Done()
3 ticker := time.NewTicker(time.Second)
4 defer ticker.Stop()
5 
6 c.Writer.Header().Set("Content-Type", "text/event-stream")
7 c.Writer.Header().Set("Cache-Control", "no-cache")
8 c.Writer.Header().Set("Connection", "keep-alive")
9 
10 c.Stream(func(w io.Writer) bool {
11 select {
12 case <-clientGone:
13 return false
14 case t := <-ticker.C:
15 snapshot, err := collectSnapshot()
16 if err != nil {
17 c.SSEvent("error", gin.H{"message": err.Error()})
18 return true
19 }
20 
21 c.SSEvent("metrics", gin.H{
22 "timestamp": t.UTC().Format(time.RFC3339),
23 "cpu": snapshot.CPUPercent,
24 "memory": snapshot.MemoryBytes,
25 "goroutines": snapshot.Goroutines,
26 "connections": snapshot.ActiveConns,
27 })
28 return true
29 }
30 })
31}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Watching the request context's Done channel lets a streaming handler stop cleanly the moment the client disconnects.
  2. 2A ticker plus a select loop turns a single HTTP response into a steady stream of timed updates.
  3. 3Returning true keeps Gin's Stream loop alive while false ends it, so the boolean is your exit switch.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Streaming server-sent events in Gin — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code