LogoPly
Features

Server-Sent Events

Stream events to browsers with the SSE helper.

Server-Sent Events

c.SSE writes a text/event-stream response and gives the handler an SSEWriter for sending events.

app.Get("/events", func(c *core.Context) {
	c.SSE(func(w *core.SSEWriter) {
		w.Retry(3000)

		ticker := time.NewTicker(5 * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				w.Event("ping", time.Now().UTC().Format(time.RFC3339))
			case <-w.Done():
				return
			}
		}
	})
})

Each event is flushed immediately. The connection stays open until the handler returns or the client disconnects.

Response headers

The helper sets:

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

Writer methods

MethodOutput
Data(value)data: value followed by a blank line
Event(name, value)event: name and data: value
Comment(text): text
Retry(ms)retry: ms
Flush()Flushes buffered output
Done()Channel closed when the client disconnects

Values must not contain raw newlines. Encode structured data as JSON first:

payload, _ := json.Marshal(message)
w.Event("message", string(payload))

Client

const events = new EventSource("/events");

events.addEventListener("ping", (event) => {
  console.log(event.data);
});

events.onerror = () => {
  console.log("connection lost, the browser will retry");
};

EventSource reconnects automatically. Use Retry to suggest a delay.

Notes

  • Each open stream holds a connection. Apply rate limits and connection limits at the proxy for public endpoints.
  • Proxies that buffer responses can delay events. Disable buffering for the SSE route.
  • The handler must return when Done() closes. Otherwise the goroutine stays alive after the client leaves.
  • Do not use Compress around SSE. Streamed responses are skipped by the compression middleware.
  • The example sends a heartbeat so idle connections and proxies keep the stream open.