1
0
mirror of https://github.com/amir20/dozzle.git synced 2025-12-21 21:33:18 +01:00
Files
dozzle/internal/support/web/sse.go
Amir Raminfar 8ee18ce9f4 more fixes
2024-09-07 16:24:42 -07:00

102 lines
1.7 KiB
Go

package support_web
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
)
type SSEWriter struct {
f http.Flusher
w http.ResponseWriter
}
type HasId interface {
MessageId() int64
}
func NewSSEWriter(ctx context.Context, w http.ResponseWriter) (*SSEWriter, error) {
f, ok := w.(http.Flusher)
if !ok {
return nil, http.ErrNotSupported
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-transform")
w.Header().Add("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("X-Accel-Buffering", "no")
sse := &SSEWriter{
f: f,
w: w,
}
return sse, nil
}
func (s *SSEWriter) Write(data []byte) (int, error) {
written, err := s.w.Write(data)
if err != nil {
return written, err
}
_, err = s.w.Write([]byte("\n\n"))
if err != nil {
return written, err
}
s.f.Flush()
return written, nil
}
func (s *SSEWriter) Ping() error {
_, err := s.Write([]byte(":ping "))
return err
}
func (s *SSEWriter) Message(data any) error {
encoded, err := json.Marshal(data)
if err != nil {
return err
}
buffer := bytes.Buffer{}
buffer.WriteString("data: ")
buffer.Write(encoded)
buffer.WriteString("\n")
if f, ok := data.(HasId); ok {
if f.MessageId() > 0 {
buffer.WriteString(fmt.Sprintf("id: %d\n", f.MessageId()))
}
}
_, err = buffer.WriteTo(s)
return err
}
func (s *SSEWriter) Event(event string, data any) error {
encoded, err := json.Marshal(data)
if err != nil {
return err
}
buffer := bytes.Buffer{}
buffer.WriteString("event: " + event + "\n")
buffer.WriteString("data: ")
buffer.Write(encoded)
buffer.WriteString("\n")
_, err = buffer.WriteTo(s)
return err
}