NFIBrokerage / slipstream

A slick WebSocket client for Phoenix Channels
https://hex.pm/packages/slipstream
Apache License 2.0
155 stars 18 forks source link

make auto-rejoin after reconnect a default feature of slipstream? #18

Closed the-mikedavis closed 3 years ago

the-mikedavis commented 3 years ago

implemented a client lately that wanted to maximize uptime to its joined topic, re-joining on disconnect (e.g. the websocket-server service restarting)

we can use an implementation like this (pardon my pseudocode):

defmodule MyClient do
  use Slipstream

  def join(topic) do
    GenServer.cast(__MODULE__, {:join, topic})
  end

  def start_link(config) do
    Slipstream.start_link(__MODULE__, config, name: __MODULE__)
  end

  @impl Slipstream
  def init(config) do
    socket =
      connect!(config)
      |> assign(:topics, [])

    {:ok, socket}
  end

  @impl Slipstream
  def handle_cast({:join, topic}, socket) do
    {:ok, socket |> assign(:topics, [topic | socket.assigns.topic]) |> join(topic)}
  end

  @impl Slipstream
  def handle_connect(socket) do
    socket =
      Enum.reduce(socket.assigns.topics, socket, fn topic, socket ->
        with false <- joined?(socket, topic),
             {:ok, socket} <- rejoin(socket, topic) do
          socket
        else
          _ -> socket
        end
      end)

    {:ok, socket}
  end
end

this isn't a worry with clients that know the topic they'd like to join ahead-of-time, but for clients that join topics dynamically, they have to roll their own re-join-after-re-connect (as above)

that implementation is not too beefy, could just write an example and be done, but it might make sense to make this the default behavior if it comes in line with phoenix.js's behavior