server_sent_event v0.4.3 ServerSentEvent.Client behaviour

Client that pulls and processes events from a server sent event stream.

This client can be used to manage reconnecting a dropped connection.

A specific client needs to implement the callbacks from this behaviour. Note there is no use macro in this module, therefore all callbacks must be implemented.

Example

defmodule AutoConnect do
  @behaviour ServerSentEvent.Client

  # Start connecting to the endpoint as soon as client is started.
  def init(state) do
    {:connect, request(state), state}
  end

  # The client has successfully connected, or reconnected, to the event stream.
  def handle_connect(_response, state) do
    {:noreply, state}
  end

  # Retry connecting to endpoint 1 second after a failure to connect.
  def handle_connect_failure(reason, state) do
    Process.sleep(1_000)
    {:connect, request(state), state}
  end

  # Immediatly try to reconnect when the connection is lost.
  def handle_disconnect(_, state) do
    {:connect, request(state), state}
  end

  # Update the running state of the client with the id of each event as it arrives.
  # This event id is used for reconnection.
  def handle_event(event, state) do
    IO.puts("I just got a new event: #{inspect(event)}")
    %{state | last_event_id: event.id}
  end

  # When stop message is received this process will exit with reason :normal.
  def handle_info(:stop, state) do
    {:stop, :normal, state}
  end

  # Not a callback but helpful pattern for creating requests in several callbacks
  defp request({url: url}) do
    Raxx.request(:GET, url)
    |> Raxx.set_header("accept", "text/event-stream")
    |> Raxx.set_header("last-event-id", state.last_event_id)
  end
end

# Starting the client
{:ok, pid} = AutoConnect.start_link(%{url: "http://www.example.com/events", last_event_id: "0"})

The client can also be added to a supervision tree

children = [
  {AutoConnect, %{url: "http://www.example.com/events", last_event_id: "0"}}
]

Link to this section Summary

Types

Return value from any callback, except handle_event/2

State of the client process

Link to this section Types

Link to this type request()
request() :: Raxx.Request.t()
Link to this type response()
response() :: Raxx.Response.t()
Link to this type return()
return() ::
  {:connect, request(), state()}
  | {:noreply, state()}
  | {:stop, atom(), state()}

Return value from any callback, except handle_event/2

This value instructs the client process with what it should do next

  • :connect start the process of connection to an event source, using the request given.
  • :noreply do nothing, and wait for next message.
  • :stop stop the client and exit with reason.
Link to this type state()
state() :: term()

State of the client process.

The initial value of this state given as the second argument to start_link/3

Link to this section Functions

Link to this function child_spec(arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function handle_packet(packet, state)
Link to this function start(module, internal_state, options \\ [])
Link to this function start_link(module, internal_state, options \\ [])

Link to this section Callbacks

Link to this callback handle_connect(response, state)
handle_connect(response(), state()) :: return()
Link to this callback handle_connect_failure(term, state)
handle_connect_failure(term(), state()) :: return()
Link to this callback handle_disconnect(term, state)
handle_disconnect(term(), state()) :: return()
Link to this callback handle_event(arg0, state)
handle_event(ServerSentEvent.t(), state()) :: state()
Link to this callback handle_info(term, state)
handle_info(term(), state()) :: return()
Link to this callback init(state)
init(state()) :: {:connect, request(), state()} | {:ok, state()}