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.
`f` MUST NOT keep the Event reference after the func returns. Use (*Event).Clone to create a copy instead.
Iteration stops if the handler returns an error or if reading fails. `ctx` is used to cancel the iteration if ctx.Done() != nil
It returns nil if all events are processed successfully.
func (*Reader) LastEventID ¶
LastEventID returns the last event ID read by the reader.
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.