Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

http.sse

import http

http exposes this as http.sse, so import http is enough and the names are called as http.sse.*. import http.sse reaches the same definitions directly.

Server-sent events (the WHATWG text/event-stream format): a one-way stream of named, identified messages that a browser’s EventSource reconnects to on its own.

Where a WebSocket gives you a duplex connection and a framing protocol to go with it, this gives you a long-lived response body and nothing else - which is all a live feed of updates actually needs, and it survives proxies that would refuse an upgrade.

import http
import http.sse

server.get('/events', @(request, response) {
  sse.stream(response, @(events) {
    iter var i = 0; i < 10; i++ {
      events.send({ tick: i }, 'tick')
      os.sleep(1)
    }
  })
})

Functions

stream()

http.sse.stream(response, producer)

Turns response into a server-sent event stream and runs producer against it.

The headers that matter are set here: text/event-stream, no caching, and X-Accel-Buffering: no for the benefit of any proxy in front that would otherwise hold the stream in a buffer and defeat the whole exercise.

Parameters

  • response (HttpResponse)
  • producer (function(1)) — called with an EventStream

last_event_id()

http.sse.last_event_id(request) -> ?string

The Last-Event-ID a reconnecting client sent, or nil.

A browser sends this automatically when EventSource reconnects, and it is how a stream resumes where it left off instead of replaying from the beginning.

Parameters

  • request (HttpRequest)

Returns ?string

parse()

http.sse.parse(text: string) -> list

Parses a text/event-stream body into a list of events, each a dictionary with event, data, id and retry.

Useful for a client consuming a stream, and for testing one.

Parameters

  • text (string)

Returns list

Classes

EventStream

class http.sse.EventStream

The writer a server-sent event stream hands to its producer.

Every method flushes, because an event that sits in a buffer is an event that has not been sent.

Constructor

http.sse.EventStream(writer)

EventStream.send()

http.sse.EventStream.send(data, event: ?string, id: ?string)

Sends one event.

data may be a string, or any value, in which case it is JSON-encoded - which is what a browser’s EventSource handler almost always parses it back out of anyway. A multi-line string is split across several data: lines, as the format requires.

Parameters

  • data (any)
  • event (?string) — the event name, which a browser dispatches under; omitted means the default message event
  • id (?string) — the event id, which the browser sends back as Last-Event-ID when it reconnects

Returns — EventStream: this same instance, for chaining

EventStream.comment()

http.sse.EventStream.comment(text: ?string)

Sends a comment line, which a client ignores.

This is the standard way to keep an idle stream alive: a proxy that closes connections after a quiet minute cannot tell a comment from real traffic.

Parameters

  • text (?string)

Returns — EventStream: this same instance, for chaining

EventStream.set_retry()

http.sse.EventStream.set_retry(milliseconds: number)

Tells the client how long to wait before reconnecting, in milliseconds.

Parameters

  • milliseconds (number)

Returns — EventStream: this same instance, for chaining

EventStream.close()

http.sse.EventStream.close()

Ends the stream. The connection closes, and a browser will reconnect unless the response said otherwise.

EventStream.is_closed()

http.sse.EventStream.is_closed() -> bool

Whether the stream has been closed.

Returns bool


2026, Richard Ore and Zuri contributors