Is it possible to detect that user was disconnected, without using additional javascript on page?
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:”).
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.
Oh, that’s pretty interesting.
Registry seems like a really cool piece of tech