Documentation
¶
Overview ¶
Example ¶
Example demonstrates a simple SSE server and client interaction.
// --- SSE Server ---
opt := config.NewOptions([]config.Option{})
opt.Addr = "127.0.0.1:0"
engine := route.NewEngine(opt)
engine.GET("/", func(ctx context.Context, c *app.RequestContext) {
println("Server Got LastEventID", GetLastEventID(&c.Request))
w := NewWriter(c)
for i := 0; i < 5; i++ {
w.WriteEvent(fmt.Sprintf("id-%d", i), "message", []byte("hello\n\nworld"))
time.Sleep(10 * time.Millisecond)
}
// [optional] it writes 0\r\n\r\n to indicate the end of chunked response
// hertz will do it after handler returns
w.Close()
})
go engine.Run()
defer engine.Close()
time.Sleep(20 * time.Millisecond) // wait for server to start
opt.Addr = testutils.GetListenerAddr(engine)
// --- SSE Client ---
c, _ := client.NewClient()
req, resp := protocol.AcquireRequest(), protocol.AcquireResponse()
req.SetRequestURI("http://" + opt.Addr + "/")
req.SetMethod("GET")
req.SetHeader(LastEventIDHeader, "id-0")
// adds `text/event-stream` to http `Accept` header
// may required for some Model Context Protocol(MCP) servers
AddAcceptMIME(req)
if err := c.Do(context.Background(), req, resp); err != nil {
panic(err)
}
r, err := NewReader(resp)
if err != nil {
panic(err)
}
defer r.Close()
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(200 * time.Millisecond)
// cancel can be used to force ForEach returns by closing the remote connection
_ = cancel
}()
err = r.ForEach(ctx, func(e *Event) error {
println("Event:", e.String())
return nil
})
if err != nil {
panic(err)
}
println("Client LastEventID", r.LastEventID())
Index ¶
- Constants
- func AddAcceptMIME(req *protocol.Request)
- func GetLastEventID(req *protocol.Request) string
- func SetLastEventID(req *protocol.Request, id string)
- type Event
- func (e *Event) AppendData(data []byte)
- func (e *Event) AppendDataString(data string)
- func (e *Event) Clone() *Event
- func (e *Event) IsSetData() bool
- func (e *Event) IsSetID() bool
- func (e *Event) IsSetRetry() bool
- func (e *Event) IsSetType() bool
- func (e *Event) Release()
- func (e *Event) Reset()
- func (e *Event) SetData(data []byte)
- func (e *Event) SetDataString(data string)
- func (e *Event) SetEvent(eventType string)
- func (e *Event) SetID(id string)
- func (e *Event) SetRetry(retry time.Duration)
- func (e *Event) String() string
- type Reader
- type Writer
Examples ¶
Constants ¶
const LastEventIDHeader = "Last-Event-ID"
Variables ¶
This section is empty.
Functions ¶
func AddAcceptMIME ¶
AddAcceptMIME adds `text/event-stream` to http `Accept` header.
This is NOT required as per spec: * User agents MAY set (`Accept`, `text/event-stream`) in request's header list.
func GetLastEventID ¶
GetLastEventID returns the value of the Last-Event-ID header.
func SetLastEventID ¶
SetLastEventID sets the Last-Event-ID header.
Types ¶
type Event ¶
type Event struct {
ID string
Type string // aka `event` field, which means event type
Data []byte
// hertz only supports reading and writing the field,
// and will not take care of retry policy, please implement on your own.
Retry time.Duration
// contains filtered or unexported fields
}
Event represents a Server-Sent Event (SSE).
func NewEvent ¶
func NewEvent() *Event
NewEvent creates a new event.
Call `Release` when you're done with the event.
func (*Event) AppendData ¶
AppendData appends data to the event data.
func (*Event) AppendDataString ¶
AppendDataString appends string data to the event data.
func (*Event) Clone ¶
Clone creates a copy of the event.
When it's no longer needed, call `Release` to return it to the pool.
func (*Event) IsSetData ¶
IsSetData returns true if the event data is set.
Please use SetData to set or AppendData to append the event data for differentiating notset or empty
func (*Event) IsSetID ¶
IsSetID returns true if the event ID is set.
Please use SetID to set the event ID for differentiating notset or empty
func (*Event) IsSetRetry ¶
IsSetRetry returns true if the retry duration is set.
Please use SetRetry to set the event retry duration for differentiating notset or empty
func (*Event) IsSetType ¶
IsSetType returns true if the event type is set.
Please use SetEvent to set the event type for differentiating notset or empty
func (*Event) SetDataString ¶
SetDataString sets the event data from a string.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader represents a reader for Server-Sent Events (SSE).
It is used to parse the response body and extract individual events.
func NewReader ¶
NewReader creates a new SSE reader from the given response.
It returns an error if the response's content type is not text/event-stream.
func (*Reader) Close ¶
Close closes the underlying response body.
NOTE: * MUST NOT call Close() and Read() / ForEach() concurrently to avoid race issue.
func (*Reader) ForEach ¶
ForEach iterates over all SSE events in the response body, invoking the provided handler function for each event.
The handler MUST NOT keep the Event reference after returning. Use (*Event).Clone to create a copy if needed.
Iteration stops when:
- The handler returns an error
- Reading fails (e.g., bufio.ErrTooLong for events exceeding buffer size)
- Context is cancelled (if ctx.Done() != nil)
- All events are processed (returns nil)
func (*Reader) LastEventID ¶
LastEventID returns the last event ID read by the reader.
func (*Reader) Read ¶
Read reads a single SSE event from the response body.
It populates the provided Event struct with the parsed data. Returns nil on success, io.EOF when no more events, or an error (e.g., bufio.ErrTooLong if an event line exceeds the buffer size). Use SetMaxBufferSize to handle larger events.
func (*Reader) SetMaxBufferSize ¶ added in v0.10.2
SetMaxBufferSize sets the maximum buffer size for the scanner.
The scanner will allocate its own buffer as needed, up to max bytes. The default max size without calling this method is bufio.MaxScanTokenSize (64KB).
It panics if it is called after reading event has started.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer represents a writer for Server-Sent Events (SSE).
It is used to write individual events to the response body.
func (*Writer) Write ¶
Write writes a single SSE event to the response body.
It returns an error if the event contains invalid characters or underlying writer fails.
func (*Writer) WriteComment ¶
WriteComment writes comment lines to the response body.
Client-side will ignore lines starting with a U+003A COLON character (:) see: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
func (*Writer) WriteEvent ¶
WriteEvent writes a single SSE event to the response body.
If id, eventType, or data are zero-length, they will be ignored. It returns an error if the event contains invalid characters or if the underlying writer fails.
func (*Writer) WriteKeepAlive ¶
WriteKeepAlive writes a comment line with "keep-alive" to the response body.
It keeps the underlying connection alive, which is useful when using proxy servers.