Documentation
¶
Overview ¶
Example ¶
Example demonstrates basic usage of the sse package: writing and reading an event.
package main
import (
"bytes"
"fmt"
"time"
"lowbit.dev/sse"
)
func main() {
buf := &bytes.Buffer{}
w := sse.NewWriter(buf)
w.Write(sse.Event{
ID: "42",
Name: "message",
Data: "hello world",
Retry: 2 * time.Second,
Extensions: map[string]string{"foo": "bar"},
})
r := sse.NewReader(buf)
evt, err := r.Read()
if err != nil {
panic(err)
}
fmt.Println(evt.ID, evt.Name, evt.Data, evt.Retry, evt.Extensions["foo"])
}
Output: 42 message hello world 2s bar
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrStreamingUnsupported = errors.New("streaming unsupported by client")
Functions ¶
This section is empty.
Types ¶
type Emitter ¶
type Emitter struct {
// contains filtered or unexported fields
}
Example ¶
ExampleEmitter demonstrates using Emitter to send events and heartbeats.
package main
import (
"fmt"
"net/http/httptest"
"lowbit.dev/sse"
)
func main() {
rw := httptest.NewRecorder()
emitter, err := sse.NewEmitter(rw)
if err != nil {
panic(err)
}
emitter.Emit(sse.Event{ID: "1", Name: "tick", Data: "tock"})
emitter.WriteHeartbeat()
fmt.Print(rw.Body.String())
}
Output: id: 1 event: tick data: tock :
func NewEmitter ¶
func NewEmitter(w http.ResponseWriter) (*Emitter, error)
func (*Emitter) ServeHeartbeats ¶
ServeHeartbeats writes a heartbeat comment to the stream at the specified interval to prevent intermediate proxies from dropping the connection.
This method is synchronous and blocks indefinitely until the provided context is canceled or a network write fails. Callers should execute it in a separate goroutine. It guarantees a clean shutdown when the request context (req.Context()) ends, ensuring no resources are leaked.
Example ¶
ExampleEmitter_ServeHeartbeats demonstrates ServeHeartbeats with context cancellation.
package main
import (
"context"
"fmt"
"net/http/httptest"
"strings"
"time"
"lowbit.dev/sse"
)
func main() {
rw := httptest.NewRecorder()
emitter, _ := sse.NewEmitter(rw)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
defer cancel()
go emitter.ServeHeartbeats(ctx, 5*time.Millisecond)
time.Sleep(15 * time.Millisecond)
out := rw.Body.String()
fmt.Print(strings.Count(out, ":\n\n")) // count heartbeats
}
Output: 2
func (*Emitter) WriteHeartbeat ¶
WriteHeartbeat sends a manual SSE comment to keep the connection alive.
type Event ¶
type Event struct {
Name string
ID string
Retry time.Duration
Data string
Extensions map[string]string
}
Event represents a single SSE event.
Example ¶
ExampleEvent demonstrates the Event struct.
package main
import (
"fmt"
"time"
"lowbit.dev/sse"
)
func main() {
e := sse.Event{
ID: "abc",
Name: "notice",
Data: "payload",
Retry: 500 * time.Millisecond,
Extensions: map[string]string{"x": "1"},
}
fmt.Println(e.ID, e.Name, e.Data, e.Retry, e.Extensions["x"])
}
Output: abc notice payload 500ms 1
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader reads SSE events from an underlying io.Reader.
Example ¶
ExampleReader demonstrates reading an SSE event from a stream.
package main
import (
"fmt"
"strings"
"lowbit.dev/sse"
)
func main() {
data := "id: 7\nevent: ping\ndata: pong\nretry: 1000\nfoo: bar\n\n"
r := sse.NewReader(strings.NewReader(data))
evt, err := r.Read()
if err != nil {
panic(err)
}
fmt.Println(evt.ID, evt.Name, evt.Data, evt.Retry, evt.Extensions["foo"])
}
Output: 7 ping pong 1s bar
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Example ¶
ExampleWriter demonstrates writing an SSE event to a stream.
package main
import (
"bytes"
"fmt"
"time"
"lowbit.dev/sse"
)
func main() {
buf := &bytes.Buffer{}
w := sse.NewWriter(buf)
w.Write(sse.Event{
ID: "99",
Name: "update",
Data: "done",
Retry: 3 * time.Second,
Extensions: map[string]string{"extra": "val"},
})
fmt.Print(buf.String())
}
Output: id: 99 event: update retry: 3000 extra: val data: done