roadrunner_sse (roadrunner v0.1.0)

View Source

Server-Sent Events (SSE) encoding helpers.

Pairs naturally with the {loop, ...} handler return: subscribe to a pubsub topic in handle/1, then call roadrunner_sse:event/1,2,3 from handle_info/3 to format each event before emitting it via the Push fun.

Example handler:

-behaviour(roadrunner_handler).
-export([handle/1, handle_info/3]).

handle(Req) ->
    ok = my_pubsub:subscribe(self(), notifications),
    Headers = [
        {~"content-type", ~"text/event-stream"},
        {~"cache-control", ~"no-cache"}
    ],
    {{loop, 200, Headers, undefined}, Req}.

handle_info({notification, Body}, Push, State) ->
    _ = Push(roadrunner_sse:event(~"notify", Body)),
    {ok, State};
handle_info(close, Push, State) ->
    _ = Push(roadrunner_sse:comment(~"bye")),
    {stop, State}.

Per the SSE spec (WHATWG HTML §9.2):

  • Each event ends with a blank line (\n\n).
  • data: may repeat — newlines in the payload split it into multiple data: lines, all reassembled into one event by the client.
  • event: is optional; an unnamed event dispatches as the generic message event in the browser.
  • id: lets the client resume from the last event seen.
  • retry: N tells the client to wait N milliseconds before reconnecting.
  • A line starting with : is a comment — useful for keep-alives over proxies that close idle connections.

Summary

Functions

SSE comment line — invisible to the client's event handler but useful for keep-alives over proxies.

Anonymous event with just a data payload.

Named event with a data payload.

Named event with an id (for client-side reconnection resume) and a data payload.

Tell the client how long (in milliseconds) to wait before retrying after a connection drop.

Functions

comment(Text)

-spec comment(Text :: binary()) -> iodata().

SSE comment line — invisible to the client's event handler but useful for keep-alives over proxies.

event(Data)

-spec event(Data :: binary()) -> iodata().

Anonymous event with just a data payload.

event(EventName, Data)

-spec event(EventName :: binary(), Data :: binary()) -> iodata().

Named event with a data payload.

event(EventName, Data, Id)

-spec event(EventName :: binary(), Data :: binary(), Id :: binary()) -> iodata().

Named event with an id (for client-side reconnection resume) and a data payload.

retry(Ms)

-spec retry(Ms :: non_neg_integer()) -> iodata().

Tell the client how long (in milliseconds) to wait before retrying after a connection drop.