diff --git a/http/sse.go b/http/sse.go new file mode 100644 index 0000000..8f72b99 --- /dev/null +++ b/http/sse.go @@ -0,0 +1,37 @@ +package webutils + +import ( + "errors" + "fmt" + "net/http" +) + +var ( + ErrWriterNotFlushable = errors.New("response writer not flushable") +) + +// SseWriter provides a simple implementation for sending data via Server Side Events +// to the client. The function runs until the dataStream channel is closed. +// The ResponseWriter must not be used after calling this function +// +// Inspired by and partially copied from https://medium.com/@rian.eka.cahya/server-sent-event-sse-with-go-10592d9c2aa1 +func SseWriter(w http.ResponseWriter, dataStream chan []byte) error { + w.Header().Set("Access-Control-Expose-Headers", "Content-Type") + + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + + flusher, ok := w.(http.Flusher) + if !ok { + return ErrWriterNotFlushable + } + for data := range dataStream { + _, err := fmt.Fprintf(w, "%s\n\n", string(data)) + if err != nil { + return err + } + flusher.Flush() + } + return nil +}