sse

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2026 License: MIT Imports: 9 Imported by: 0

README

sse

Go Reference

A small, allocation-light server implementation of the WHATWG Server-Sent Events protocol.

Message and Comment are safe to call from multiple goroutines and the hot path does no heap allocations.

Documentation

Overview

Package sse implements the server side of the WHATWG Server-Sent Events protocol.

See https://html.spec.whatwg.org/multipage/server-sent-events.html for the wire format and the rules clients follow when interpreting an event stream.

Example
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httptest"

	"github.com/typelate/sse"
)

func main() {
	handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		stream, ok := sse.New(w, req, http.StatusOK)
		if !ok {
			http.Error(w, "streaming unsupported", http.StatusInternalServerError)
			return
		}
		_ = stream.Message([]byte("first"), sse.WithID("1"), sse.WithEvent("greet"))
		_ = stream.Comment("keep-alive")
		_ = stream.Message([]byte("multi\nline"))
	})
	srv := httptest.NewServer(handler)
	defer srv.Close()

	res, err := http.Get(srv.URL)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", body)

}
Output:
id: 1
event: greet
data: first

: keep-alive

data: multi
data: line

Index

Examples

Constants

View Source
const (
	// LastEventIDRequestHeaderKey is the header a client sets when
	// reconnecting, carrying the id of the last event it received so the
	// server can resume the stream.
	LastEventIDRequestHeaderKey = "Last-Event-Id"

	ContentTypeResponseHeaderKey   = "Content-Type"
	ContentTypeResponseHeaderValue = "text/event-stream; charset=utf-8"

	ConnectionResponseHeaderKey   = "Connection"
	ConnectionResponseHeaderValue = "keep-alive"

	// CacheControlResponseHeaderKey is set to no-cache so intermediaries
	// do not buffer the stream.
	CacheControlResponseHeaderKey   = "Cache-Control"
	CacheControlResponseHeaderValue = "no-cache"
)

Variables

View Source
var ErrInvalidField = errors.New("sse: field contains forbidden CR or LF")

ErrInvalidField is returned when an id, event, or comment value contains a CR or LF, which the SSE wire format reserves as line terminators.

Functions

This section is empty.

Types

type Message

type Message struct {
	// contains filtered or unexported fields
}

Message is an SSE event, configured via the With* options.

type MessageOption

type MessageOption func(*Message)

MessageOption configures a Message.

func WithBytesBuffer

func WithBytesBuffer(buf *bytes.Buffer) MessageOption

WithBytesBuffer reuses a caller-provided buffer for assembling the wire representation, useful for sync.Pool style allocation avoidance. The buffer is reset before use.

func WithEvent

func WithEvent(event string) MessageOption

WithEvent sets the event type. The value must not contain CR or LF.

func WithID

func WithID(id string) MessageOption

WithID sets the id field, which the client echoes back via Last-Event-ID after a disconnect. Pass an empty string to reset the client's stored id. The value must not contain CR or LF.

func WithIntID

func WithIntID(id int) MessageOption

WithIntID is a convenience for WithID(strconv.Itoa(id)).

func WithRetry

func WithRetry(d time.Duration) MessageOption

WithRetry sets the reconnection time the client should wait after the connection drops. Sub-millisecond precision is dropped; the wire field is an integer count of milliseconds.

type Response

type Response struct {
	// contains filtered or unexported fields
}

Response is an open Server-Sent Events stream. Message and Comment are safe to call from multiple goroutines.

func New

func New(res http.ResponseWriter, req *http.Request, code int) (*Response, bool)

New writes the SSE response headers and the supplied status code, then returns a *Response for sending events. The boolean is false if the underlying ResponseWriter does not implement http.Flusher; in that case no headers are written and the caller should respond with an error.

func (*Response) Comment

func (res *Response) Comment(text string) error

Comment writes a colon-prefixed comment line. Clients ignore comments; they are useful as keep-alive pings to prevent proxies from closing idle connections. The text must not contain CR or LF.

func (*Response) LastEventID

func (res *Response) LastEventID() (string, bool)

LastEventID returns the value of the Last-Event-ID request header. The boolean is false if the header was absent or empty.

func (*Response) Message

func (res *Response) Message(data []byte, opts ...MessageOption) error

Message sends an event to the client and flushes the connection. Multi-line data is split into one "data:" line per line; \r\n and \r line terminators inside data are normalized to \n.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL