diff --git a/lib/algora/restream/websocket.ex b/lib/algora/restream/websocket.ex index af1c6b4..ce6c7fb 100644 --- a/lib/algora/restream/websocket.ex +++ b/lib/algora/restream/websocket.ex @@ -4,8 +4,17 @@ defmodule Algora.Restream.Websocket do alias Algora.{Accounts, Chat} - def start_link(%{url: url, video: video}) do - WebSockex.start_link(url, __MODULE__, %{url: url, video: video}) + def start_link(%{url: url, video: video} = opts) do + retry = opts[:retry] || 0 + restart = opts[:restart] || 0 + Logger.info("Starting WebSocket: #{video.id} (restart: #{restart}, retry: #{retry})") + + WebSockex.start_link(url, __MODULE__, %{ + url: url, + video: video, + restart: restart, + retry: retry + }) end def handle_frame({:text, msg}, state) do @@ -23,9 +32,41 @@ defmodule Algora.Restream.Websocket do end end - def handle_disconnect(_reason, state) do - Logger.error("WebSocket disconnected: #{state.video.id}") - {:reconnect, state} + def handle_connect(_conn, state) do + if state.restart == 0 and state.retry == 0 do + Logger.info("WebSocket connected: #{state.video.id}") + else + Logger.info( + "WebSocket reconnected: #{state.video.id} (restart: #{state.restart}, retry: #{state.retry})" + ) + end + + {:ok, state} + end + + def handle_disconnect(reason, state) do + Logger.error("WebSocket disconnected: #{state.video.id} (reason: #{inspect(reason)})") + + # latest_video = Library.get_latest_video(Accounts.get_user!(state.video.user_id)) + # socket_video = Library.get_video!(state.video.id) + # if socket_video.id == latest_video.id and socket_video.is_live and state.retry < 10 do + + if state.retry < 3 do + :timer.sleep(:timer.seconds(min(2 ** state.retry, 60))) + state = %{state | retry: state.retry + 1} + {:reconnect, state} + else + :timer.sleep(:timer.seconds(min(2 ** state.restart, 60))) + state = %{state | restart: state.restart + 1, retry: 0} + + Task.Supervisor.start_child( + Algora.TaskSupervisor, + fn -> Algora.Restream.Websocket.start_link(state) end, + restart: :transient + ) + + {:ok, state} + end end defp handle_payload(%{"eventPayload" => %{"contentModifiers" => %{"whisper" => true}}}, state) do