Detect that user diconnected from liveview socket

Is it possible to detect that user was disconnected, without using additional javascript on page?

:wave:

Maybe you could use the terminate/2 callback?

I haven’t tried it myself with the live views, but maybe something like

defmodule SomeLiveView do
  use Phoenix.LiveView

  # ... other callbacks ...

  @impl true
  def terminate(reason, socket) do
    if disconnected?(reason) do
      # do stuff
    end
  end

  defp disconnected?(reason) do
    case reason do
      :shutdown -> true
      {:shutdown, shutdown_reason} when shutdown_reason in [:left, :closed] -> true
      _other -> false
    end
  end
end

As for where this reason comes from, it comes from phoenix’s cowboy handler and here’re the possible values (scroll down to “The following terminate reasons are defined for Websocket connections:”).

Maybe you can use the approach in this Stack Overflow answer from @chrismccord

1 Like

Except ChannelWatcher can be now replaced with Registry with a callback passed to :listeners.

Also, it has a real possibility to introduce false positives (since it tracks channels, not sockets), where a user is actually still connected to the socket, but the liveview channel is dead (for whatever reason, maybe it just had done what it needed to do, and was removed from the page) since the two are not linked and a dying channel won’t take down the socket so the tcp connection would stay open.

1 Like

Oh, that’s pretty interesting.

Registry seems like a really cool piece of tech :slight_smile: