Skip to content

Instantly share code, notes, and snippets.

@lotusirous
Created February 25, 2020 13:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lotusirous/2a40a23469a7b0f7870698bbe528ea1e to your computer and use it in GitHub Desktop.
Save lotusirous/2a40a23469a7b0f7870698bbe528ea1e to your computer and use it in GitHub Desktop.
A sample server sent event with golang
package main
import (
"context"
"fmt"
"io"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/go-chi/chi"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
)
var pingInterval = time.Second * 10
// HandleLiveLog returns an http.HandlerFunc that processes an http.Request
// to server sent event.
func HandleLiveLog() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
h := w.Header()
h.Set("Content-Type", "text/event-stream")
h.Set("Cache-Control", "no-cache")
h.Set("Connection", "keep-alive")
h.Set("X-Accel-Buffering", "no")
f, ok := w.(http.Flusher)
if !ok {
return
}
io.WriteString(w, ": ping\n\n")
f.Flush()
L:
for {
select {
case <-ctx.Done():
logrus.Info("events: stream cancelled")
break L
case <-time.After(pingInterval):
io.WriteString(w, ": heart beat\n\n")
f.Flush()
default:
fmt.Fprintf(w, "%s\n", time.Now().Format(time.RFC1123))
f.Flush()
time.Sleep(2 * time.Second)
}
}
io.WriteString(w, "event: error\ndata: eof\n\n")
f.Flush()
logrus.Info("events: stream closed")
}
}
func main() {
r := chi.NewRouter()
r.Get("/livelog", HandleLiveLog())
srv := &http.Server{
Addr: ":4343",
ReadTimeout: 75 * time.Second,
Handler: r,
}
ctx, cancel := context.WithCancel(context.Background())
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(c)
select {
case <-ctx.Done():
case <-c:
cancel()
}
}()
var g errgroup.Group
g.Go(func() error {
return srv.ListenAndServe()
})
g.Go(func() error {
<-ctx.Done()
return srv.Shutdown(ctx)
})
if err := g.Wait(); err != nil {
logrus.WithError(err).Info("shutdown server")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment