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
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Watching the request context's Done channel lets a streaming handler stop cleanly the moment the client disconnects.
- 2A ticker plus a select loop turns a single HTTP response into a steady stream of timed updates.
- 3Returning true keeps Gin's Stream loop alive while false ends it, so the boolean is your exit switch.
Related explainers
go
package main import ( "errors"
Parsing and validating CLI flags in Go
cli-parsing
validation
error-handling
Intermediate
8 steps
rust
use std::sync::{mpsc, Arc, Mutex}; use std::thread; use std::time::Duration;
Building a thread pool in Rust
concurrency
channels
thread-pool
Advanced
9 steps
python
import csv import io from datetime import datetime
Streaming a CSV export in Flask
streaming
generators
csv
Intermediate
9 steps
go
package cache import ( "container/list"
Building a generic LRU cache in Go
lru-cache
generics
linked-list
Intermediate
8 steps
go
package model import ( "encoding/json"
Custom JSON marshaling in Go
json
serialization
interfaces
Intermediate
5 steps
python
import csv import io from datetime import date
Streaming a CSV export in FastAPI
streaming
async-generators
csv
Advanced
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/streaming-server-sent-events-in-gin-explained-go-3bde/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.