Skip to content

Instantly share code, notes, and snippets.

@xinau
Created March 24, 2022 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xinau/3f86e2c32ef3266ad1fa2a4983cafd97 to your computer and use it in GitHub Desktop.
Save xinau/3f86e2c32ef3266ad1fa2a4983cafd97 to your computer and use it in GitHub Desktop.
Server-Sent Events in Go
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
)
func send(ctx context.Context, rw http.ResponseWriter, ivl time.Duration) {
flusher, _ := rw.(http.Flusher)
tck := time.NewTicker(ivl)
defer tck.Stop()
for {
select {
case <-ctx.Done():
return
case date := <-tck.C:
fmt.Fprintln(rw, date.Format(time.StampNano))
flusher.Flush()
}
}
}
func parse(data string) time.Duration {
dur, err := time.ParseDuration(data)
if err != nil {
return 5 * time.Second
}
return dur
}
func ticker(rw http.ResponseWriter, req *http.Request) {
rw.Header().Set("Cache-Control", "no-cache")
rw.Header().Set("Connection", "keep-alive")
rw.Header().Set("Content-Type", "text/event-stream")
if _, ok := rw.(http.Flusher); !ok {
http.Error(rw, "client doesn't support streaming", http.StatusBadRequest)
return
}
ivl := req.URL.Query().Get("interval")
send(req.Context(), rw, parse(ivl))
}
func main() {
log.Printf("info: starting server on :5000")
http.HandleFunc("/tick", ticker)
http.ListenAndServe(":5000", nil)
}
#!/usr/bin/env bash
if [ "$#" -ne "1" ]; then
echo "error: interval is missing"
echo "usage: ${0} <interval>"
exit 1
fi
curl -N "localhost:5000/tick?interval=${1}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment